#!/usr/bin/env nu
# scripts/witness.nu — run a SOW's contracts for one phase; append a JSONL receipt.
# Usage: nu witness.nu <sow.ncl> <receipt.jsonl> --phase static|runtime|lock --wo <slug>
#
# Dumb executor: understands nothing about the SOW's actual content, only its
# contract shape (Appendix B, .coder/2026-07-03_governed-delivery-mode.plan.md).
# NEVER signs anything itself (§7.5) — minisign has no password env var by
# design; a passphrase-protected key cannot be used non-interactively. This
# script prints the exact signing command and stops; a human runs it,
# separately, in their own shell.

def main [
    sow_path: string,
    receipt_path: string,
    --phase: string = "static",
    --wo: string = "",
    --pubkey: string = "",
]: nothing -> nothing {
    let verify_result = (do { ^minisign -V -p $pubkey -m $sow_path -x $"($sow_path).minisig" } | complete)
    if ($pubkey | is-not-empty) and $verify_result.exit_code != 0 {
        print $"REJECTED: ($sow_path) signature does not verify against ($pubkey) — no witness, no start."
        exit 1
    }
    if ($pubkey | is-not-empty) {
        print $"Signature verified: ($sow_path)"
    }

    let sow = (nickel export $sow_path --format json | from json)
    let ts  = (date now | format date "%+")
    let wo_id = (if ($wo | is-not-empty) { $wo } else { $sow.id })

    let searched = ($sow.existing_mechanisms_searched? | default [])
    if ($searched | is-empty) {
        print "REJECTED: existing_mechanisms_searched is empty — a draft SOW must record what was searched for an existing mechanism before proposing a new one."
        exit 1
    }

    let matching = ($sow.contracts | where kind == $phase)
    if ($matching | is-empty) {
        print $"($sow.id) [($phase)] — no contracts for this phase, nothing to check"
        return
    }

    # Checks run from the governed repository's root — the parent of the
    # .governance/ directory the SOW lives in (§7.4 guarantees that location).
    # A relative path in a check must never silently pass from an unrelated
    # cwd: `! grep` on a file the cwd doesn't contain exits 0 (falsación F0).
    let sow_dir = ($sow_path | path expand | path dirname)
    let gov_root = if (($sow_dir | path basename) == ".governance") {
        $sow_dir | path dirname
    } else {
        $env.PWD
    }

    let results = ($matching | each {|c|
        let out = (do { cd $gov_root; ^bash -c $c.check } | complete)
        let exempt_paths = ($c.exempt? | default [] | each {|e| $e.path })
        if ($exempt_paths | is-empty) {
            {
                wo: $wo_id, contract: $c.id, phase: $c.kind,
                exit: $out.exit_code,
                verdict: (if $out.exit_code == 0 { "pass" } else { "fail" }),
                detail: ($out.stdout | str trim | str substring 0..300),
                ts: $ts,
            }
        } else {
            # Exempt-bearing contract: the check must emit one violating path
            # per stdout line. Exemption subtracts exact paths — the contract
            # is exempt only when EVERY violation is exempt; any non-exempt
            # remainder fails. Substring matching against the whole output
            # would exempt unrelated violations (plan §9.0 N2).
            let violations = ($out.stdout | lines | each {|l| $l | str trim } | where {|l| $l | is-not-empty })
            let remaining = ($violations | where {|v| $v not-in $exempt_paths })
            let counts = $"violations=($violations | length) exempt=(($violations | length) - ($remaining | length)) remaining=($remaining | length)"
            {
                wo: $wo_id, contract: $c.id, phase: $c.kind,
                exit: $out.exit_code,
                verdict: (if $out.exit_code == 0 { "pass" } else if ($remaining | is-empty) { "exempt" } else { "fail" }),
                detail: (($counts + (if ($remaining | is-empty) { "" } else { ": " + ($remaining | str join " ") })) | str substring 0..300),
                ts: $ts,
            }
        }
    })

    let unsigned_lines = ($results | each {|r| $r | to json --raw } | str join "\n")
    $"($unsigned_lines)\n" | save --append --raw $receipt_path

    let failed = ($results | where verdict == "fail")
    if ($failed | is-not-empty) {
        print $"($sow.id) [($phase)] — REJECTED: ($failed | length) contract\(s) failed"
        $failed | select contract exit detail | print
        exit 1
    }

    print $"($sow.id) [($phase)] — ACCEPTED: ($results | length) contract\(s) pass"
    print ""
    print "Receipt written, NOT signed. Sign it yourself, in your own shell:"
    let sign_cmd = ("  minisign -S -s ~/.minisign/witness.key -m " + $receipt_path
        + " -x " + $receipt_path + ".minisig"
        + " -t \"wo=" + $wo_id + " " + ($results | length | into string) + " contract(s) checked at " + $ts + "\""
        + " -c \"ontoref witness receipt\"")
    print $sign_cmd
}
