# Contract tests for the G-1 (warrant) and G-2 (edge reconciliation) gates.
# Exports a flat record of booleans; the gate is: `nickel export` must succeed AND
# no field may be `false` (checked by the runner). Kept assertion-only so a broken
# contract surfaces as a `false`, and a broken SCHEMA surfaces as an export error.

let s   = import "../schemas/core.ncl" in
let inv = import "../defaults/edge-inverses.ncl" in

# A node carrying a valid warrant must merge cleanly with the Node contract.
let node_with_warrant = s.Node & {
  id = "t", name = "t", pole = 'Yang, level = 'Axiom, description = "d",
  warrant = [{ kind = 'Interview, ref = "2026-06-10-ontology-completion" }],
} in

# A node with NO warrant must still validate (default = []).
let node_default = s.Node & {
  id = "t2", name = "t2", pole = 'Yin, level = 'Practice, description = "d",
} in

# An edge with a reconciled symbolic weight and a real kind must validate.
let edge_ok = s.Edge & { from = "a", to = "b", kind = 'Resolves, weight = 'High } in

{
  warrant_ref_accepts_valid   = (node_with_warrant.warrant |> std.array.length) == 1,
  warrant_defaults_to_empty   = (node_default.warrant |> std.array.length) == 0,
  edge_symbolic_weight_ok     = edge_ok.weight == 'High,
  edge_real_kind_ok           = edge_ok.kind == 'Resolves,
  inverses_cover_nine_kinds   = (inv.inverses |> std.record.fields |> std.array.length) == 9,
  symmetric_are_four          = (inv.symmetric |> std.array.length) == 4,
  symmetric_are_self_inverse  =
    inv.symmetric
    |> std.array.all (fun k => (inv.inverses |> std.record.get k) == k),
  contains_is_asymmetric      = inv.inverses.Contains == "IsContainedIn",
  manifests_inverse_correct   = inv.inverses.ManifestsIn == "IsManifestationOf",
}
