@sabaiway/agent-workflow-kit 1.49.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/SKILL.md +1 -1
- package/bridges/antigravity-cli-bridge/SKILL.md +17 -4
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +73 -17
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +271 -13
- package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +76 -0
- package/bridges/antigravity-cli-bridge/capability.json +166 -5
- package/bridges/antigravity-cli-bridge/references/driving-agy.md +6 -2
- package/bridges/antigravity-cli-bridge/references/models-and-flags.md +3 -2
- package/bridges/antigravity-cli-bridge/references/review-prompt.md +1 -1
- package/bridges/codex-cli-bridge/SKILL.md +8 -1
- package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +133 -0
- package/bridges/codex-cli-bridge/bin/codex-review.sh +22 -9
- package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +165 -2
- package/bridges/codex-cli-bridge/capability.json +118 -2
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/modes/review-ledger.md +1 -1
- package/references/modes/review-state.md +2 -2
- package/tools/detect-backends.mjs +6 -5
- package/tools/manifest/schema.md +62 -0
- package/tools/manifest/validate.mjs +327 -0
- package/tools/review-ledger-core.mjs +74 -0
- package/tools/review-ledger-write.mjs +19 -10
- package/tools/review-ledger.mjs +21 -12
- package/tools/review-state.mjs +89 -28
|
@@ -18,8 +18,10 @@
|
|
|
18
18
|
// round VANISHED unclassified (D6 — no-repro-no-fold; `refuted` is the honest
|
|
19
19
|
// phantom lane); refuses while the changed source surface exceeds the diff cap
|
|
20
20
|
// without a recorded segment size-cap override (D4). Integrity binding (Decision 7):
|
|
21
|
-
// each NON-degraded backend needs
|
|
22
|
-
//
|
|
21
|
+
// each NON-degraded backend needs an ATTESTING code receipt for the current tree
|
|
22
|
+
// (the shared review-ledger-core predicate: grounded AND probe:false — a probe,
|
|
23
|
+
// unmarked or malformed marker never attests), so a round cannot be recorded for a
|
|
24
|
+
// tree no bridge really reviewed.
|
|
23
25
|
// recordTriage — the classification that BREAKS the deadlock: each surviving blocking finding of a
|
|
24
26
|
// SEGMENT round classified fixable-bug / inherent-layer-residual / escalate /
|
|
25
27
|
// refuted (v4). No teeth (a triage is exactly what lets the next round proceed),
|
|
@@ -51,6 +53,9 @@ import {
|
|
|
51
53
|
decideStop,
|
|
52
54
|
validateRecord,
|
|
53
55
|
} from './review-ledger.mjs';
|
|
56
|
+
// The SHARED attesting-receipt predicate (D3) — read straight from the neutral core, the same one
|
|
57
|
+
// review-state and the round cross-check use: one definition of "this receipt may attest a tree".
|
|
58
|
+
import { summarizeReviewReceiptsForTree, describeMissingReviewAttestation } from './review-ledger-core.mjs';
|
|
54
59
|
// The NEUTRAL shared changed-surface computation (BUGFREE-2 / D4): the D4 diff-cap and the
|
|
55
60
|
// fold-completeness coverage gate consume ONE computation, so they can never drift. The writer
|
|
56
61
|
// imports the NEUTRAL module, never the runner (the sole-tree-toucher boundary, codex R2 — an
|
|
@@ -253,17 +258,20 @@ export const recordRound = (params, deps = {}) => {
|
|
|
253
258
|
const v = validateRecord(record);
|
|
254
259
|
if (!v.ok) throw stop(`refusing to record a malformed round: ${v.reason}`);
|
|
255
260
|
|
|
256
|
-
// Integrity binding: each NON-degraded backend needs
|
|
257
|
-
//
|
|
261
|
+
// Integrity binding: each NON-degraded backend needs an ATTESTING receipt for this tree — a round
|
|
262
|
+
// cannot be recorded for a tree no bridge really reviewed. A degraded backend minted no receipt.
|
|
263
|
+
// The predicate is the SHARED one (review-ledger-core), the same review-state and the round
|
|
264
|
+
// cross-check read — a probe receipt never counted as a review, and the stated reason names WHICH
|
|
265
|
+
// exclusion applied, because the recoveries differ (run a real review / refresh the bridge / fix
|
|
266
|
+
// the receipt source / re-run grounded) and a silent "no receipt" would hide that.
|
|
258
267
|
const receiptsPath = deps.receiptsPath ?? resolveReceiptsPath(cwd, env);
|
|
259
268
|
const { receipts } = receiptsPath ? readReceipts(receiptsPath, deps.readFile) : { receipts: [] };
|
|
260
269
|
for (const b of backends) {
|
|
261
270
|
if (b.degraded) continue;
|
|
262
|
-
const own = receipts.filter(
|
|
263
|
-
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
throw stop(`refusing to record a round for ${b.backend}: no grounded code receipt for the current tree — run its review wrapper (codex-review code / agy-review code --facts @f) first, or mark the backend degraded with a reason`);
|
|
271
|
+
const own = receipts.filter((r) => r.backend === b.backend);
|
|
272
|
+
const failure = describeMissingReviewAttestation(summarizeReviewReceiptsForTree(own, fingerprint));
|
|
273
|
+
if (failure !== null) {
|
|
274
|
+
throw stop(`refusing to record a round for ${b.backend}: no grounded code receipt for the current tree can attest this round — ${failure}; run its real review (codex-review code / agy-review code --facts @f), or mark the backend degraded with a reason`);
|
|
267
275
|
}
|
|
268
276
|
}
|
|
269
277
|
|
|
@@ -518,7 +526,8 @@ record appends one review round. The JSON payload carries { loop, round, origi
|
|
|
518
526
|
segment size-cap override (D4); while the segment lacks a quality-green gate-run at the
|
|
519
527
|
current fingerprint (D5 — run the FULL matrix first: run-gates.mjs --record; a --only
|
|
520
528
|
subset or a tree-changed run never satisfies; red PROCESS gates never block); or when a
|
|
521
|
-
non-degraded backend lacks
|
|
529
|
+
non-degraded backend lacks an ATTESTING code receipt for the current tree (grounded AND
|
|
530
|
+
probe:false — a probe, unmarked or malformed marker never attests).
|
|
522
531
|
classify appends one triage record. The JSON payload carries { loop, round, classifications } (each
|
|
523
532
|
{ findingKey, class, accepted, testId, note }). A fixable-bug REQUIRES a testId — the
|
|
524
533
|
red→green test that pins the fold, formatted "<test-file>#<test-name-pattern>" (write it
|
package/tools/review-ledger.mjs
CHANGED
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
// no reviewer ready); when no plan is in flight (the review-state naming convention);
|
|
20
20
|
// when the tree is clean (nothing to review); when the cwd is not a git work tree; and
|
|
21
21
|
// when the in-flight plan-execution SEGMENT is `converged` or `resolved-residual` (its
|
|
22
|
-
// latest round's non-degraded backends carry
|
|
23
|
-
// fingerprint
|
|
22
|
+
// latest round's non-degraded backends carry ATTESTING code receipts for the recorded
|
|
23
|
+
// fingerprint — the shared review-ledger-core predicate: grounded AND probe:false, a
|
|
24
|
+
// probe/unmarked/malformed marker never attests — and a recorded 0/0 is
|
|
25
|
+
// ship-class-consistent with those receipts).
|
|
24
26
|
// exit 1 for any DIRTY in-flight plan-execution segment that is neither `converged` nor
|
|
25
27
|
// `resolved-residual` — `triage-required`, `continue`, OR no round/receipt recorded in
|
|
26
28
|
// the CURRENT segment (a dirty active plan with an empty/stale/other-segment ledger is a
|
|
@@ -83,6 +85,8 @@ import {
|
|
|
83
85
|
filterLoopRecords,
|
|
84
86
|
filterSegmentRecords,
|
|
85
87
|
roundSequenceIntact,
|
|
88
|
+
summarizeReviewReceiptsForTree,
|
|
89
|
+
describeMissingReviewAttestation,
|
|
86
90
|
} from './review-ledger-core.mjs';
|
|
87
91
|
export {
|
|
88
92
|
LEDGER_BASENAME,
|
|
@@ -270,22 +274,27 @@ export const decideStop = (records, { cap = REVIEW_CAP, currentFingerprint = nul
|
|
|
270
274
|
// ── receipt cross-check (integrity binding, Decision 7) ──────────────────────────────────────────
|
|
271
275
|
|
|
272
276
|
// receiptCrossCheck(round, receipts, fingerprint) → { ok, reason }. For each NON-degraded backend of
|
|
273
|
-
// `round`:
|
|
274
|
-
// tree no bridge reviewed — AND a recorded ship-class 0/0 must not coexist with a non-ship
|
|
277
|
+
// `round`: an ATTESTING receipt must exist for (backend, fingerprint) — a round cannot pass for a
|
|
278
|
+
// tree no bridge really reviewed — AND a recorded ship-class 0/0 must not coexist with a non-ship
|
|
275
279
|
// verdict. A degraded backend minted no receipt (it ran no real review) and is exempt.
|
|
280
|
+
// The attesting predicate is the SHARED one (review-ledger-core), the same review-state reads: this
|
|
281
|
+
// gate used to filter raw fields and take `own[own.length - 1]`, so a probe receipt landing AFTER a
|
|
282
|
+
// real one became the authoritative verdict — a late probe SHIP could bury a real REWORK and let
|
|
283
|
+
// BOTH gates report convergence (D3). The summary's `receipt` is the latest ATTESTING one, never
|
|
284
|
+
// simply the last line.
|
|
276
285
|
export const receiptCrossCheck = (round, receipts, fingerprint) => {
|
|
277
286
|
for (const b of round.backends) {
|
|
278
287
|
if (b.degraded) continue;
|
|
279
|
-
const own = receipts.filter(
|
|
280
|
-
|
|
281
|
-
);
|
|
282
|
-
if (
|
|
283
|
-
return { ok: false, reason: `no grounded code receipt for ${b.backend} at the recorded fingerprint
|
|
288
|
+
const own = receipts.filter((r) => r.backend === b.backend);
|
|
289
|
+
const summary = summarizeReviewReceiptsForTree(own, fingerprint);
|
|
290
|
+
const failure = describeMissingReviewAttestation(summary);
|
|
291
|
+
if (failure !== null) {
|
|
292
|
+
return { ok: false, reason: `no grounded code receipt for ${b.backend} at the recorded fingerprint can attest this review round — ${failure}` };
|
|
284
293
|
}
|
|
285
294
|
if (b.blockers === 0 && b.majors === 0) {
|
|
286
|
-
const
|
|
287
|
-
if (!isShipVerdict(
|
|
288
|
-
return { ok: false, reason: `${b.backend} recorded 0 blockers/0 majors but its receipt verdict "${
|
|
295
|
+
const { verdict } = summary.receipt;
|
|
296
|
+
if (!isShipVerdict(verdict)) {
|
|
297
|
+
return { ok: false, reason: `${b.backend} recorded 0 blockers/0 majors but its attesting receipt verdict "${verdict}" is not ship-class` };
|
|
289
298
|
}
|
|
290
299
|
}
|
|
291
300
|
}
|
package/tools/review-state.mjs
CHANGED
|
@@ -30,6 +30,18 @@
|
|
|
30
30
|
// Informational receipts NEVER satisfy (nor fail) the tree check: plan/diff-mode receipts
|
|
31
31
|
// (artifact ≠ "code") and continuations (fresh:false — agy --continue/--conversation cannot attest
|
|
32
32
|
// a folded tree; only a fresh grounded re-run mints a gate-satisfying receipt).
|
|
33
|
+
// PROBE receipts never satisfy either (BRIDGE-MODES-CATALOG, D3): a CODEX_PROBE=1 / AGY_PROBE=1
|
|
34
|
+
// review runs with the frontier-model/max-effort guard OFF, so the wrappers stamp `probe:true` and
|
|
35
|
+
// this checker drops those receipts — PER RECEIPT, so a normal receipt at the same fingerprint still
|
|
36
|
+
// satisfies, and a backend whose ONLY current receipts are probes fails with its own stated reason
|
|
37
|
+
// (never the stale one). Every receipt from a marker-aware wrapper SELF-DECLARES — `probe` is written
|
|
38
|
+
// on every successful review, true or false — so a NON-BOOLEAN or ABSENT marker is rejected
|
|
39
|
+
// fail-closed: silence is not a declaration, and the probe status of an unmarked receipt is
|
|
40
|
+
// untrustworthy whoever wrote it (the pre-D3 wrappers honoured the probe env vars while writing no
|
|
41
|
+
// marker; a hand-written line is no better evidence). Deliberately NOT keyed on wrapperVersion: the
|
|
42
|
+
// version bumps in a different release phase than the marker lands, so a version floor would reject
|
|
43
|
+
// the very receipts the current wrappers write. Accepted cost (maintainer, 2026-07-15): a pre-D3
|
|
44
|
+
// receipt stops satisfying — re-run the review with a marker-aware bridge.
|
|
33
45
|
//
|
|
34
46
|
// The fingerprint is the ONE canonical uncommitted-state identity — sha256 over: staged diff +
|
|
35
47
|
// unstaged diff + untracked-not-ignored file contents (binary untracked files, symlinks, and
|
|
@@ -61,7 +73,14 @@ import { resolveActivityRecipe, planRecipe, DISPLAY_ALIASES } from './recipes.mj
|
|
|
61
73
|
import { CONFIG_REL, fail, loadConfig } from './orchestration-config.mjs';
|
|
62
74
|
// The NEUTRAL ledger read-core (AD-050): review-state reads the review-ledger ONLY for the degraded
|
|
63
75
|
// exemption, through the neutral core — never review-ledger.mjs (which imports THIS module, the cycle).
|
|
64
|
-
import {
|
|
76
|
+
import {
|
|
77
|
+
resolveLedgerPath,
|
|
78
|
+
resolveBase,
|
|
79
|
+
readLedger,
|
|
80
|
+
filterSegmentRecords,
|
|
81
|
+
roundSequenceIntact,
|
|
82
|
+
summarizeReviewReceiptsForTree,
|
|
83
|
+
} from './review-ledger-core.mjs';
|
|
65
84
|
|
|
66
85
|
export const RECEIPTS_BASENAME = 'agent-workflow-review-receipts.jsonl';
|
|
67
86
|
export const PLANS_REL = 'docs/plans';
|
|
@@ -290,29 +309,35 @@ export const readReceipts = (path, readFile = readFileSync) => {
|
|
|
290
309
|
return { receipts, malformed };
|
|
291
310
|
};
|
|
292
311
|
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
// ungrounded — current-fingerprint fresh receipts exist but every one carries grounded:false;
|
|
312
|
+
// Per-backend receipt status for the current fingerprint, over the ONE shared attesting-receipt
|
|
313
|
+
// predicate (review-ledger-core) that the round cross-check and the round writer read too — two
|
|
314
|
+
// gates disagreeing about what counts as an attestation is the class AD-050 closed:
|
|
315
|
+
// current — an ATTESTING receipt exists (fresh code, probe:false, grounded) — its verdict rides;
|
|
316
|
+
// ungrounded — real (probe:false) current receipts exist but every one carries grounded:false;
|
|
317
|
+
// probe — current receipts exist and EVERY one is a well-formed probe (D3);
|
|
318
|
+
// rejected — current receipts exist, none attests, and >=1 marker was malformed or absent;
|
|
301
319
|
// stale — this backend has receipts, none for the current fingerprint (edited after review);
|
|
302
|
-
// missing — no
|
|
320
|
+
// missing — no receipt from this backend at all.
|
|
321
|
+
// The counts state what was dropped, so a PASS over a partially-excluded set still says so
|
|
322
|
+
// (No-silent-failures) and the --json surface can show it.
|
|
303
323
|
export const backendReceiptStatus = (receipts, backend, fingerprint) => {
|
|
304
324
|
const own = receipts.filter((r) => r.backend === backend);
|
|
305
|
-
const
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
325
|
+
const summary = summarizeReviewReceiptsForTree(own, fingerprint);
|
|
326
|
+
const counts = {
|
|
327
|
+
probeExcluded: summary.probeExcluded,
|
|
328
|
+
markerRejected: summary.markerRejected,
|
|
329
|
+
unmarkedRejected: summary.unmarkedRejected,
|
|
330
|
+
};
|
|
331
|
+
if (summary.state === 'current') {
|
|
332
|
+
return { state: 'current', verdict: summary.receipt.verdict ?? 'unknown', grounded: true, timestamp: summary.receipt.timestamp ?? null, ...counts };
|
|
310
333
|
}
|
|
311
|
-
if (
|
|
312
|
-
|
|
313
|
-
return { state: 'ungrounded', verdict: latest.verdict ?? 'unknown', grounded: false, timestamp: latest.timestamp ?? null };
|
|
334
|
+
if (summary.state === 'ungrounded') {
|
|
335
|
+
return { state: 'ungrounded', verdict: summary.receipt.verdict ?? 'unknown', grounded: false, timestamp: summary.receipt.timestamp ?? null, ...counts };
|
|
314
336
|
}
|
|
315
|
-
|
|
337
|
+
if (summary.state === 'probe' || summary.state === 'rejected') {
|
|
338
|
+
return { state: summary.state, verdict: null, grounded: null, timestamp: null, ...counts };
|
|
339
|
+
}
|
|
340
|
+
return { state: own.length > 0 ? 'stale' : 'missing', verdict: null, grounded: null, timestamp: null, ...counts };
|
|
316
341
|
};
|
|
317
342
|
|
|
318
343
|
// ── the degraded exemption (AD-050): read the review-ledger for a recorded current-tree degrade ────
|
|
@@ -411,6 +436,17 @@ export const buildState = ({ cwd, env = process.env, detect = detectBackends, ls
|
|
|
411
436
|
};
|
|
412
437
|
};
|
|
413
438
|
|
|
439
|
+
// Why a backend's current-tree receipts were all rejected — the two causes read differently and
|
|
440
|
+
// have different recoveries (fix the file vs refresh the bridge), so they are never collapsed.
|
|
441
|
+
const rejectionCause = (b) => {
|
|
442
|
+
const parts = [];
|
|
443
|
+
if (b.markerRejected > 0) parts.push(`${b.markerRejected} with a malformed probe marker`);
|
|
444
|
+
if (b.unmarkedRejected > 0) {
|
|
445
|
+
parts.push(`${b.unmarkedRejected} with no probe marker — silence is not a declaration, so the probe status is untrustworthy; re-run the review with a bridge that marks its runs`);
|
|
446
|
+
}
|
|
447
|
+
return parts.join(' + ');
|
|
448
|
+
};
|
|
449
|
+
|
|
414
450
|
// The normative --check decision (the header contract, in order). → { code, reason }.
|
|
415
451
|
export const decideCheck = (state) => {
|
|
416
452
|
// A DETECTOR FAILURE is unknown state, not "no reviewer ready" — the advisory tools warn and
|
|
@@ -449,23 +485,37 @@ export const decideCheck = (state) => {
|
|
|
449
485
|
// stays verdict-blind: the exemption proves the degrade was RECORDED, never that the tree converged.
|
|
450
486
|
const exempt = new Set(state.degradedExempt);
|
|
451
487
|
const failing = state.backends.filter((b) => b.state !== 'current' && !exempt.has(b.backend));
|
|
488
|
+
// A receipt dropped for an untrustworthy probe marker is never silently dropped either (D3): it
|
|
489
|
+
// cannot fail a tree that other receipts satisfy, but a report over a partially-rejected set says
|
|
490
|
+
// so. It counts only the exclusions NOT already named per backend — a FAILING `rejected` backend
|
|
491
|
+
// prints its own cause below, and repeating it in the summary is noise. Every other exclusion (a
|
|
492
|
+
// partial one on a satisfied backend, or one on a degraded-exempt backend) still needs a voice.
|
|
493
|
+
const namedPerBackend = new Set(failing.filter((b) => b.state === 'rejected').map((b) => b.backend));
|
|
494
|
+
const untrustedTotal = state.backends
|
|
495
|
+
.filter((b) => !namedPerBackend.has(b.backend))
|
|
496
|
+
.reduce((n, b) => n + (b.markerRejected ?? 0) + (b.unmarkedRejected ?? 0), 0);
|
|
497
|
+
const markerNote = untrustedTotal > 0
|
|
498
|
+
? ` — ${untrustedTotal} receipt(s) rejected: an untrustworthy probe marker (malformed, or absent — silence is not a declaration) — fail-closed; inspect ${state.receiptsPath}`
|
|
499
|
+
: '';
|
|
452
500
|
if (failing.length === 0) {
|
|
453
501
|
if (exempt.size === 0) {
|
|
454
|
-
return { code: 0, reason: `every recipe-named backend has a fresh grounded receipt for the current tree (${state.requiredBackends.join(' + ')})${malformedNote}${ledgerNote}` };
|
|
502
|
+
return { code: 0, reason: `every recipe-named backend has a fresh grounded receipt for the current tree (${state.requiredBackends.join(' + ')})${markerNote}${malformedNote}${ledgerNote}` };
|
|
455
503
|
}
|
|
456
|
-
return { code: 0, reason: `every recipe-named backend reviewed the current tree (${state.requiredBackends.join(' + ')}) — degraded-exempt (recorded degraded for the current tree in the review ledger): ${[...exempt].join(', ')}${malformedNote}${ledgerNote}` };
|
|
504
|
+
return { code: 0, reason: `every recipe-named backend reviewed the current tree (${state.requiredBackends.join(' + ')}) — degraded-exempt (recorded degraded for the current tree in the review ledger): ${[...exempt].join(', ')}${markerNote}${malformedNote}${ledgerNote}` };
|
|
457
505
|
}
|
|
458
506
|
const parts = failing.map((b) => {
|
|
459
507
|
if (b.state === 'ungrounded') return `${b.backend}: only ungrounded receipts for the current tree — re-run grounded (--facts)`;
|
|
508
|
+
if (b.state === 'probe') return `${b.backend}: only probe receipts for the current tree (CODEX_PROBE=1 / AGY_PROBE=1 relaxes the quality guards) — a probe review never attests; re-run a real one`;
|
|
509
|
+
if (b.state === 'rejected') return `${b.backend}: current-tree receipts rejected — ${rejectionCause(b)} (fail-closed); inspect ${state.receiptsPath}`;
|
|
460
510
|
if (b.state === 'stale') return `${b.backend}: receipts exist but none matches the current tree (edited after review) — run a fresh review`;
|
|
461
511
|
return `${b.backend}: no receipt — run its review wrapper`;
|
|
462
512
|
});
|
|
463
|
-
return { code: 1, reason: `${parts.join('; ')}${malformedNote}${ledgerNote}` };
|
|
513
|
+
return { code: 1, reason: `${parts.join('; ')}${markerNote}${malformedNote}${ledgerNote}` };
|
|
464
514
|
};
|
|
465
515
|
|
|
466
516
|
// ── rendering ───────────────────────────────────────────────────────────────────────
|
|
467
517
|
|
|
468
|
-
const STATE_GLYPH = { current: '✓', ungrounded: '✗', stale: '✗', missing: '✗' };
|
|
518
|
+
const STATE_GLYPH = { current: '✓', ungrounded: '✗', probe: '✗', rejected: '✗', stale: '✗', missing: '✗' };
|
|
469
519
|
|
|
470
520
|
const formatHuman = (state, check) => {
|
|
471
521
|
const src = state.resolved.source === 'config' ? `from ${CONFIG_REL}` : 'computed default';
|
|
@@ -488,10 +538,17 @@ const formatHuman = (state, check) => {
|
|
|
488
538
|
? `current (verdict: ${b.verdict}, grounded, ${b.timestamp ?? '?'})`
|
|
489
539
|
: b.state === 'ungrounded'
|
|
490
540
|
? `ungrounded for the current tree (verdict: ${b.verdict}) — a grounded fresh run is required`
|
|
491
|
-
: b.state === '
|
|
492
|
-
? '
|
|
493
|
-
:
|
|
494
|
-
|
|
541
|
+
: b.state === 'probe'
|
|
542
|
+
? 'only probe receipts for the current tree (quality guards relaxed) — a probe review never attests'
|
|
543
|
+
: b.state === 'rejected'
|
|
544
|
+
? `current-tree receipts rejected — ${rejectionCause(b)} (fail-closed)`
|
|
545
|
+
: b.state === 'stale'
|
|
546
|
+
? 'stale — no receipt matches the current tree (edited after review)'
|
|
547
|
+
: 'missing — no receipt from this backend';
|
|
548
|
+
const excludedTag = b.probeExcluded || b.markerRejected || b.unmarkedRejected
|
|
549
|
+
? ` [excluded: ${b.probeExcluded} probe, ${b.markerRejected} malformed-marker, ${b.unmarkedRejected} unmarked]`
|
|
550
|
+
: '';
|
|
551
|
+
lines.push(` ${exempt.has(b.backend) ? '⊘' : STATE_GLYPH[b.state]} ${b.backend}: ${detail}${excludedTag}${exemptTag}`);
|
|
495
552
|
}
|
|
496
553
|
lines.push(` check: ${check.code === 0 ? 'PASS' : 'FAIL'} — ${check.reason}`);
|
|
497
554
|
return lines.join('\n');
|
|
@@ -507,7 +564,11 @@ recomputes the canonical uncommitted-state fingerprint (staged + unstaged + untr
|
|
|
507
564
|
the review-payload domain), reads the receipt file the review wrappers append to
|
|
508
565
|
(<git dir>/${RECEIPTS_BASENAME}; AW_REVIEW_RECEIPTS overrides), and reports per-backend receipt
|
|
509
566
|
presence + verdict + grounding for the CURRENT tree. Plan/diff-mode receipts and continuations
|
|
510
|
-
(fresh:false) are informational-only — they never satisfy the tree check
|
|
567
|
+
(fresh:false) are informational-only — they never satisfy the tree check, and neither does a PROBE
|
|
568
|
+
receipt (probe:true — a CODEX_PROBE=1 / AGY_PROBE=1 run has the quality guards off). The probe
|
|
569
|
+
filter is per receipt, so a real receipt at the same fingerprint still satisfies. Every marker-aware
|
|
570
|
+
wrapper writes the probe field on EVERY review (true or false), so a malformed OR absent marker is
|
|
571
|
+
rejected fail-closed — silence is not a declaration.
|
|
511
572
|
|
|
512
573
|
--check exits 0/1 per the normative contract in the tool header: 0 for solo / no plan in flight /
|
|
513
574
|
a clean tree / not-a-git-tree / all recipe-named backends receipted-current-and-grounded OR
|