Merge ci-evidence-added 1e044509 into master (gate: green on f3a9e8c4, recorded by tools/ci/pre-push.sh; landed on the box mirror under the exception declared by main: main's ruling, 7 Oct 2026 19:5x UK: the GitHub account is suspended, lanes land on the box mirror's master, the box gate stamp is the verdict; GitHub gets the fast-forward when it answers)
This commit is contained in:
commit
f7c6d5116f
3 changed files with 33 additions and 9 deletions
|
|
@ -7,12 +7,13 @@
|
|||
{
|
||||
"cell": "experiment:connected-state",
|
||||
"status": "FAIL",
|
||||
"evidence": "docs/analysis/class-v6"
|
||||
"evidence": "docs/analysis/class-v6/connected-state.md"
|
||||
},
|
||||
{
|
||||
"cell": "experiment:mixed-fp32",
|
||||
"status": "FAIL",
|
||||
"evidence": "docs/analysis/class-v6"
|
||||
"evidence": "docs/analysis/class-v6/mixed-fp32.md; docs/analysis/class-v6/rows/pow-07-fp32-unreachable.md"
|
||||
}
|
||||
]
|
||||
],
|
||||
"note": " Evidence narrowed at 21:3x UK from the class-v6 directory to the two experiments' own files (a directory citation bound every file beneath it to these rows and refused every other lane's class-v6 landing); the verdicts are unchanged."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ check() { # <base> <head> ; prints "refused ..." lines; returns 1 when any
|
|||
local base="$1" head="$2" rc=0
|
||||
git cat-file -e "$head:$REG" 2>/dev/null || return 0
|
||||
local tmp_h tmp_b; tmp_h=$(mktemp); tmp_b=$(mktemp); git show "$head:$REG" > "$tmp_h"; git show "$base:$REG" > "$tmp_b" 2>/dev/null || : > "$tmp_b"
|
||||
local touched; touched=$(git diff --name-only "$base" "$head" --)
|
||||
python3 - "$tmp_h" "$tmp_b" "$head" "$touched" <<'PY' || rc=1
|
||||
local touched added; touched=$(git diff --name-only "$base" "$head" --); added=$(git diff --name-only --diff-filter=A "$base" "$head" --)
|
||||
python3 - "$tmp_h" "$tmp_b" "$head" "$touched" "$added" <<'PY' || rc=1
|
||||
import json, sys, subprocess, os
|
||||
h = json.load(open(sys.argv[1])); b = json.load(open(sys.argv[2])) if os.path.getsize(sys.argv[2]) else {}
|
||||
head = sys.argv[3]; touched = [t for t in sys.argv[4].split('\n') if t]
|
||||
head = sys.argv[3]; touched = [t for t in sys.argv[4].split('\n') if t]; added = set(t for t in sys.argv[5].split('\n') if t)
|
||||
cases = lambda r: [t for s in r.get('suites', []) for t in s.get('tests', [])]
|
||||
hb = {c['id']: c for c in cases(b)}; refused = []
|
||||
approved = bool(h.get('approval')); pinned = h.get('pinned_manifest_sha')
|
||||
|
|
@ -62,6 +62,7 @@ for c in cases(h):
|
|||
REG_PATH = os.environ.get('REGISTRY_PATH', 'docs/plans/igneum-2.0-test-registry.json')
|
||||
for t in touched:
|
||||
if t == REG_PATH: continue # the registry names itself as GOV-02's evidence (the approval recorded in it); it always moves with itself
|
||||
if t in added: continue # a file first appearing in the tree is the evidence arriving, not evidence changing under a row: a row that cited it before it landed stands (lane D's class, 8 October 2026 21:2x UK); only a MODIFIED or deleted evidence file must move its rows
|
||||
owners = [ids for p, ids in named.items() if t == p or t.startswith(p + '/')]
|
||||
if not owners and not t.startswith('docs/analysis/'): continue
|
||||
ids = sorted({i for ids in owners for i in ids})
|
||||
|
|
@ -97,7 +98,9 @@ PY
|
|||
git checkout -q -b e base; echo r2 > docs/analysis/row.md; git -c user.name=t -c user.email=t@t commit -qam touched && git tag touched
|
||||
# evidence-with-row: the same change with X-2's updated moved
|
||||
git checkout -q -b e2 base; echo r2 > docs/analysis/row.md; mk docs/plans/igneum-2.0-test-registry.json 1 - '{"X-1": {}, "X-2": {"run_status": "RUNNING", "evidence_path": "docs/analysis/row.md", "updated": "t1"}}'; git -c user.name=t -c user.email=t@t commit -qam with-row && git tag with-row
|
||||
# stale: PASS on evidence pinned to another manifest
|
||||
# added: a NEW evidence file another lane's row already cites lands free (the row cited it before it existed; rule 2 binds modified files only)
|
||||
git checkout -q -b a base; mkdir -p docs/analysis/new; echo n1 > docs/analysis/new/log.tsv; mk docs/plans/igneum-2.0-test-registry.json 1 - '{"X-1": {}, "X-2": {"run_status": "RUNNING", "evidence_path": "docs/analysis/row.md; docs/analysis/new/log.tsv", "updated": "t0"}}'; git add -A; git -c user.name=t -c user.email=t@t commit -qm added && git tag added
|
||||
git checkout -q -b a2 added; echo n2 > docs/analysis/new/log.tsv; git -c user.name=t -c user.email=t@t commit -qam added-then-touched && git tag added-touched
|
||||
git checkout -q -b s base; mk docs/plans/igneum-2.0-test-registry.json 1 aaaaaaaa '{"X-1": {"run_status": "PASS", "evidence_path": "evidence/a.log", "updated": "t1", "evidence_record": {"manifest_sha": "bbbbbbbb"}}, "X-2": {}}'; git -c user.name=t -c user.email=t@t commit -qam stale && git tag stale
|
||||
# self-ref: a row names the registry itself as its evidence; a registry change must not trip rule 2 on it
|
||||
git checkout -q -b r base; mk docs/plans/igneum-2.0-test-registry.json 1 - '{"X-1": {"run_status": "RUNNING", "evidence_path": "evidence/a.log", "updated": "t1"}, "X-2": {"run_status": "RUNNING", "evidence_path": "docs/plans/igneum-2.0-test-registry.json", "updated": "t0"}}'; git -c user.name=t -c user.email=t@t commit -qam self-ref && git tag self-ref
|
||||
|
|
@ -108,10 +111,12 @@ PY
|
|||
out=$(bash "$ME" base pass-missing 2>&1) && { echo "self-test failed: a PASS naming a missing path passed"; fails=1; }; case "$out" in *"not in the tree"*) ;; *) echo "self-test failed: the missing path was not named: $out"; fails=1 ;; esac
|
||||
out=$(bash "$ME" base touched 2>&1) && { echo "self-test failed: a touched evidence file without its row passed"; fails=1; }; case "$out" in *"X-2"*"move together"*) ;; *) echo "self-test failed: the unmoved row was not named: $out"; fails=1 ;; esac
|
||||
bash "$ME" base with-row >/dev/null 2>&1 || { echo "self-test failed: a touched evidence file with its row updated was refused: $(bash "$ME" base with-row 2>&1)"; fails=1; }
|
||||
bash "$ME" base added >/dev/null 2>&1 || { echo "self-test failed: a new evidence file a row already cites was refused on arrival: $(bash "$ME" base added 2>&1)"; fails=1; }
|
||||
out=$(bash "$ME" added added-touched 2>&1) && { echo "self-test failed: the same file modified after it landed passed without its row"; fails=1; }
|
||||
out=$(bash "$ME" base stale 2>&1) && { echo "self-test failed: a PASS on stale evidence passed"; fails=1; }; case "$out" in *"stale evidence"*) ;; *) echo "self-test failed: the stale evidence was not named: $out"; fails=1 ;; esac
|
||||
bash "$ME" base self-ref >/dev/null 2>&1 || { echo "self-test failed: a row naming the registry itself as evidence tripped the move-together rule on a registry change: $(bash "$ME" base self-ref 2>&1)"; fails=1; }
|
||||
out=$(bash "$ME" base unapproved 2>&1) && { echo "self-test failed: a run_status without approval passed"; fails=1; }; case "$out" in *"thresholds before results"*) ;; *) echo "self-test failed: the missing approval was not named: $out"; fails=1 ;; esac
|
||||
[ "$fails" = 0 ] && echo "self-test passed: a PASS must name evidence that exists (tree or box); a touched evidence file moves with its registry row; evidence pinned to another manifest cannot be PASS; a run_status needs the registry's approval"
|
||||
[ "$fails" = 0 ] && echo "self-test passed: a PASS must name evidence that exists (tree or box); a modified evidence file moves with its registry row and a new one lands free; evidence pinned to another manifest cannot be PASS; a run_status needs the registry's approval"
|
||||
exit $fails
|
||||
fi
|
||||
[ $# -eq 2 ] || { echo "usage: registry-evidence-check.sh <base> <head> | --self-test" >&2; exit 2; }
|
||||
|
|
|
|||
|
|
@ -74,6 +74,16 @@ function record(reg, map, batch) {
|
|||
if (status === 'DEFERRED') { status = 'NOT RUN'; deferral = cell.deferral || 'deferred by the founder'; }
|
||||
if (!DECISIONS.has(status)) throw new Error(`cell ${cell.cell}: status ${cell.status} is not one of NOT RUN, BLOCKED, FAIL, PASS (RUNNING reads as NOT RUN in progress; DEFERRED as NOT RUN with a deferral note)`);
|
||||
const method = cell.method || batch.method; if (!METHODS.has(method)) throw new Error(`cell ${cell.cell}: method must be one of ${[...METHODS].join(', ')} (never conflated); got ${method}`);
|
||||
// evidence paths (the coordinator's and lane D's classes, 8 October 2026 21:3x UK): a tree path must exist at record time and name a file,
|
||||
// never a directory (a directory citation makes every file beneath it the row's evidence and trips the move-together rule on every
|
||||
// other lane's landing); an absolute path or a box path (host:/path) is outside the tree and is not checked here (rule 1 reads it at the merge)
|
||||
for (const one of String(cell.evidence || '').split(';').map((x) => x.trim()).filter(Boolean)) {
|
||||
if (one.startsWith('/') || one.includes(':/')) continue;
|
||||
if (process.env.TEST_RECORD_NO_TREE === '1') continue;
|
||||
const abs = path.resolve(ROOT, one);
|
||||
if (!fs.existsSync(abs)) throw new Error(`cell ${cell.cell}: evidence ${one} is not in the tree at record time (cite only files that exist here; another lane's unlanded file is cited after it lands)`);
|
||||
if (fs.statSync(abs).isDirectory()) throw new Error(`cell ${cell.cell}: evidence ${one} is a directory; name the file (a directory citation binds every file beneath it to this row)`);
|
||||
}
|
||||
const missing = Object.entries(cell.prereqs || {}).filter(([, v]) => v !== 'present').map(([k]) => k);
|
||||
if (missing.length) status = 'BLOCKED';
|
||||
// a cell may narrow its write to named cases of the cell ("cases": [...]) so an incident on one case never writes a cell's other cases
|
||||
|
|
@ -112,7 +122,7 @@ function record(reg, map, batch) {
|
|||
}
|
||||
const acceptSnapshot = (reg) => JSON.stringify(casesOf(reg).map((c) => { const o = { id: idOf(c) }; for (const k of ACCEPT_KEYS) if (k in c) o[k] = c[k]; return o; }));
|
||||
if (args.includes('--self-test')) {
|
||||
const d = fs.mkdtempSync('/tmp/test-record-'); let fails = 0;
|
||||
const d = fs.mkdtempSync('/tmp/test-record-'); let fails = 0; process.env.TEST_RECORD_NO_TREE = '1'; // the fixture cells cite fake paths; the tree rule is exercised by its own cases below
|
||||
const reg = { cases: [
|
||||
{ id: 'C1', method: 'Automated', accept: 'one million vectors agree' }, { id: 'C2', method: 'Automated', accept: 'parser refuses ten thousand malformed' },
|
||||
{ id: 'C3', method: 'Manual review', accept: 'the reviewer signs' }, { id: 'C4', method: 'Automated; manual', accept: 'frozen verify time holds' } ] };
|
||||
|
|
@ -128,6 +138,14 @@ if (args.includes('--self-test')) {
|
|||
record(reg, map, { run_id: 'r1r', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'RUNNING', evidence: '/e/pow.log' }] });
|
||||
if (!(reg.cases[0].run_status === 'NOT RUN' && reg.cases[0].in_progress_since)) { console.log('self-test failed: RUNNING did not become NOT RUN with in_progress_since'); fails = 1; }
|
||||
let badStatus = false; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'GREEN' }] }); } catch { badStatus = true; }
|
||||
delete process.env.TEST_RECORD_NO_TREE; let badPath = ''; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'FAIL', evidence: `${d}/missing.log`.replace(/^\//, 'rel/') }] }); } catch (e) { badPath = String(e.message); }
|
||||
if (!/not in the tree at record time/.test(badPath)) { console.log(`self-test failed: an evidence path not in the tree was accepted at record time: ${badPath}`); fails = 1; }
|
||||
fs.mkdirSync(`${d}/dir`); const relDir = path.relative(ROOT, `${d}/dir`); let badDir = '';
|
||||
try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'FAIL', evidence: relDir }] }); } catch (e) { badDir = String(e.message); }
|
||||
if (!/is a directory/.test(badDir)) { console.log(`self-test failed: a directory cited as evidence was accepted: ${badDir}`); fails = 1; }
|
||||
fs.writeFileSync(`${d}/dir/f.log`, 'x'); let okFile = true; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'FAIL', evidence: `${relDir}/f.log` }] }); } catch { okFile = false; }
|
||||
if (!okFile) { console.log('self-test failed: a tree file that exists was refused as evidence'); fails = 1; }
|
||||
process.env.TEST_RECORD_NO_TREE = '1';
|
||||
if (!badStatus) { console.log('self-test failed: a status outside the vocabulary was accepted'); fails = 1; }
|
||||
let badMethod = false; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', cells: [{ cell: 'pow', status: 'PASS' }] }); } catch { badMethod = true; }
|
||||
if (!badMethod) { console.log('self-test failed: a batch with no method was accepted (methods are never conflated)'); fails = 1; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue