@sabaiway/agent-workflow-kit 2.0.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 +29 -0
- package/SKILL.md +1 -1
- package/bridges/antigravity-cli-bridge/SKILL.md +9 -4
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +52 -9
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +98 -11
- package/bridges/antigravity-cli-bridge/capability.json +11 -8
- 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/capability.json +1 -1
- package/package.json +1 -1
- package/tools/detect-backends.mjs +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ Semantically versioned ([semver](https://semver.org)), newest first. The `versio
|
|
|
4
4
|
is the current release. `upgrade` mode reads a project's `docs/ai/.workflow-version` and applies
|
|
5
5
|
every `migrations/<version>-<slug>.md` newer than it, in semver order.
|
|
6
6
|
|
|
7
|
+
## 2.1.0 — agy code review fails CLOSED pre-spend: grounded facts required, `--ungrounded` is the explicit escape (AD-058)
|
|
8
|
+
|
|
9
|
+
> ### ⚠ the bundled antigravity bridge takes MAJOR 3.0.0 — bare `agy-review code` now refuses
|
|
10
|
+
>
|
|
11
|
+
> `agy-review code` without a NON-EMPTY `--facts` payload exits 2 **before spending a run**
|
|
12
|
+
> (previously: a loud warning, then a spent subscription run whose `grounded:false` receipt the
|
|
13
|
+
> review-state gate rejects — a guaranteed-wasted spend). Scripts calling bare `agy-review code`
|
|
14
|
+
> must add `--facts @f` (grounded) or `--ungrounded` (explicit throwaway opinion; the receipt still
|
|
15
|
+
> records `grounded:false` and never attests). `plan`/`diff` modes and continuations are unchanged.
|
|
16
|
+
> The kit itself is a MINOR carrier — the incompatibility is created, and declared, by the bridge.
|
|
17
|
+
|
|
18
|
+
A **fail-closed** release (kit MINOR carrying antigravity-cli-bridge **3.0.0** MAJOR in-tarball;
|
|
19
|
+
codex-cli-bridge 2.8.0 / engine 1.17.0 / memory 2.3.0 unchanged; the deployment-lineage head stays
|
|
20
|
+
`2.0.0`). One theme: **a run that cannot produce a usable result refuses before the money is spent.**
|
|
21
|
+
|
|
22
|
+
- **The refusal prints the recovery:** the exact `grounding.mjs` invocation — resolved from the
|
|
23
|
+
wrapper's own location across the three real install layouts (monorepo canon / deployed skills
|
|
24
|
+
sibling / kit-bundled mirror), quoted so an install path with spaces still yields a runnable
|
|
25
|
+
command — plus the `agy-review code --facts @<file>` re-run line.
|
|
26
|
+
- **Escapes, both honest:** `--ungrounded` (code-mode only, contradicts `--facts`, refused on a
|
|
27
|
+
continuation) and `AGY_PROBE=1` (a probe may now run ungrounded — a probe receipt never attests
|
|
28
|
+
either way; its `modeCatalog` descriptor now marks the facts file optional).
|
|
29
|
+
- **Every declaration home moves in lockstep** (drift-guarded both directions): `--help` ⟷
|
|
30
|
+
`capability.json` (`roles.review.contract` + `modeCatalog` `review.code` operands/guardrails +
|
|
31
|
+
the `AGY_PROBE` env-hook) ⟷ the kit registry mirror (`tools/detect-backends.mjs`) ⟷ `SKILL.md` ⟷
|
|
32
|
+
`references/driving-agy.md` / `models-and-flags.md` / `review-prompt.md`.
|
|
33
|
+
- **Receipt contract scoped honestly:** in `code` mode an absent/empty facts payload now means NO
|
|
34
|
+
run and NO receipt; the `grounded:false`-on-empty clause applies to `plan`/`diff` only.
|
|
35
|
+
|
|
7
36
|
## 2.0.0 — Bridge mode catalog (manifest-as-source) + a review receipt that SELF-DECLARES (AD-057)
|
|
8
37
|
|
|
9
38
|
> ### ⚠ BREAKING — a review receipt written before this release no longer attests a tree
|
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: agent-workflow-kit
|
|
|
3
3
|
description: Deploy or upgrade a portable AI-agent memory-and-workflow system in any project. Use when the user wants to bootstrap `docs/ai/` + an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) + cap/archive/index enforcement in a new or existing repo, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-kit` / `/agent-workflow-kit upgrade`. Triggers on phrases like "set up the memory system", "deploy the AI workflow here", "bootstrap docs/ai", "upgrade the workflow".
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
metadata:
|
|
6
|
-
version: '2.
|
|
6
|
+
version: '2.1.0'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# agent-workflow-kit
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: antigravity-cli-bridge
|
|
3
3
|
description: Delegate work to Google's Antigravity CLI (`agy`) — the successor to Gemini CLI — to reach Gemini, Claude, and GPT-OSS models under a Google AI Pro/Ultra subscription from the terminal. Use when the user wants to run a headless `agy` prompt, hand a focused task or second-opinion review to `agy`, install or authenticate Antigravity CLI, check or economise its quota/models, bridge project context into `agy`, set up a second delegated-execution backend beside Codex, or troubleshoot `agy` flags, models, auth, conversations, or its no-JSON headless behaviour.
|
|
4
4
|
metadata:
|
|
5
|
-
version: '
|
|
5
|
+
version: '3.0.0'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# antigravity-cli-bridge
|
|
@@ -118,11 +118,16 @@ review **guesses** (stale-model and partial-diff false positives). `agy-review`
|
|
|
118
118
|
POSTURE + a **model/cutoff GUARD** + your **`--facts`** (the verified facts the model reviews AGAINST)
|
|
119
119
|
+ **`--decided`** (the anti-circling list) + **`--focus`** + the artifact + a strict output shape, then
|
|
120
120
|
delegates execution to `agy-run` (one home for the timeout, the subscription invariant, and the byte
|
|
121
|
-
ceiling).
|
|
121
|
+
ceiling). In `code` mode grounding **fails closed**: without a non-empty `--facts` payload the wrapper
|
|
122
|
+
refuses **before spending a run** (an ungrounded code receipt records `grounded:false`, which the
|
|
123
|
+
review-state gate rejects — the run would attest nothing). The explicit escapes are `--ungrounded`
|
|
124
|
+
(a throwaway opinion) and `AGY_PROBE=1` (a probe never attests anyway); `plan`/`diff` keep the loud
|
|
125
|
+
warning and proceed.
|
|
122
126
|
|
|
123
127
|
```bash
|
|
124
|
-
agy-review code
|
|
125
|
-
agy-review
|
|
128
|
+
agy-review code --facts @facts.md [--decided @decided.md] [--focus "…"] # the repo-complete diff (facts REQUIRED — fails closed pre-spend)
|
|
129
|
+
agy-review code --ungrounded # explicit escape: throwaway ungrounded opinion (receipt never attests)
|
|
130
|
+
agy-review plan <plan-file> [--facts @f] … # critique a plan (no facts ⇒ loud warning)
|
|
126
131
|
agy-review diff <diff-file> [--facts @f] … # review a supplied diff
|
|
127
132
|
agy-review --continue --decided @round1.md --focus "still-open items" # round-2 delta, no re-assembly
|
|
128
133
|
```
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
# 1. POSTURE read-only second-opinion reviewer; findings only, no edits/commits
|
|
15
15
|
# 2. GUARD do NOT opine on AI model names/versions or your knowledge cutoff
|
|
16
16
|
# 3. FACTS "## Grounded facts — review AGAINST these, do NOT guess the code"
|
|
17
|
-
# (
|
|
17
|
+
# (code mode REFUSES pre-spend without a non-empty payload — escapes:
|
|
18
|
+
# --ungrounded / AGY_PROBE=1; plan/diff omitted -> a LOUD stderr warning)
|
|
18
19
|
# 4. DECIDED "## Decisions already made / already addressed — do NOT re-raise"
|
|
19
20
|
# (optional; the anti-circling lever — the round-2 payload)
|
|
20
21
|
# 5. FOCUS the merged --focus / trailing focus text (optional)
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
# facts (--facts), the already-decided list (--decided), and the focus (--focus).
|
|
28
29
|
#
|
|
29
30
|
# Usage (installed on PATH as `agy-review`):
|
|
30
|
-
# agy-review code [--facts @f] [--decided @f] [--focus "…"] [extra focus…]
|
|
31
|
+
# agy-review code [--facts @f] [--ungrounded] [--decided @f] [--focus "…"] [extra focus…]
|
|
31
32
|
# agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus "…"]
|
|
32
33
|
# agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus "…"]
|
|
33
34
|
# agy-review --continue [--decided @f] [--focus "…"] # round-2 delta (no mode, no re-assembly)
|
|
@@ -55,19 +56,22 @@ case "${1:-}" in
|
|
|
55
56
|
agy-review — grounded read-only ADVISORY review by Google's Antigravity CLI (agy; subscription-only).
|
|
56
57
|
|
|
57
58
|
Usage:
|
|
58
|
-
agy-review code [--facts @f] [--decided @f] [--focus "…"] [extra focus…]
|
|
59
|
+
agy-review code [--facts @f] [--ungrounded] [--decided @f] [--focus "…"] [extra focus…]
|
|
59
60
|
agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus "…"]
|
|
60
61
|
agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus "…"]
|
|
61
62
|
|
|
62
63
|
Flags:
|
|
63
|
-
--facts @f — verified facts the review runs AGAINST (
|
|
64
|
+
--facts @f — verified facts the review runs AGAINST (code mode REQUIRES a non-empty payload; plan/diff warn loudly when omitted)
|
|
65
|
+
--ungrounded — deliberately ungrounded CODE review, a throwaway opinion (code mode only, contradicts --facts; the receipt records grounded:false and never attests)
|
|
64
66
|
--decided @f — already-decided / already-addressed list; do NOT re-raise (anti-circling; the round-2 payload)
|
|
65
67
|
--focus "…" — extra focus (repeatable; code mode also takes trailing focus words)
|
|
66
68
|
|
|
67
69
|
Grounding:
|
|
68
70
|
grounded review — agy reads NOTHING by default, an ungrounded review GUESSES:
|
|
69
71
|
--facts @f = the verified facts to review AGAINST; --decided @f = decisions
|
|
70
|
-
already made, do NOT re-raise (anti-circling)
|
|
72
|
+
already made, do NOT re-raise (anti-circling). code mode REQUIRES a non-empty
|
|
73
|
+
--facts payload and refuses BEFORE spending a run (escapes: --ungrounded,
|
|
74
|
+
AGY_PROBE=1); plan/diff proceed with a loud warning
|
|
71
75
|
|
|
72
76
|
Notes:
|
|
73
77
|
pre-dispatch host-diff: before the FIRST dispatch of this bridge, diff its declared networkHosts
|
|
@@ -88,7 +92,8 @@ Receipt:
|
|
|
88
92
|
sockets — are excluded from the domain entirely, untracked symlinks/directories ride as
|
|
89
93
|
name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict
|
|
90
94
|
recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK);
|
|
91
|
-
grounded = whether a NON-EMPTY --facts payload was supplied (
|
|
95
|
+
grounded = whether a NON-EMPTY --facts payload was supplied (code mode refuses pre-spend without
|
|
96
|
+
one — no run, no receipt — unless --ungrounded/AGY_PROBE=1; in plan/diff an empty payload records
|
|
92
97
|
grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts
|
|
93
98
|
payload; a continuation receipt is fresh:false (informational-only — it cannot attest the
|
|
94
99
|
folded tree); probe = whether the run relaxed the quality guards (AGY_PROBE=1), written on EVERY
|
|
@@ -101,7 +106,7 @@ Settings file (KEY=VALUE, parsed never sourced; env wins over file, file wins ov
|
|
|
101
106
|
AGY_HARD_TIMEOUT — hard wall-clock cap, duration string like 5m/30m/90s (built-in default 30m)
|
|
102
107
|
AGY_REVIEW_ALLOW_ADDDIR — boolean 0/1: 1 arms the oversized --add-dir escape (re-enables the Issue-001 stall risk; default 0)
|
|
103
108
|
|
|
104
|
-
Closed grammar: unknown flags are rejected; no '--' passthrough (the
|
|
109
|
+
Closed grammar: unknown flags are rejected; no '--' passthrough (the flag escape is --ungrounded; the env escapes are AGY_PROBE=1 and AGY_REVIEW_ALLOW_ADDDIR=1).
|
|
105
110
|
Requires at run time: the agy CLI on PATH + a Google AI subscription login (--help needs neither).
|
|
106
111
|
HELP
|
|
107
112
|
exit 0
|
|
@@ -220,7 +225,7 @@ DEFAULT_AGY_REVIEW_MODEL="Gemini 3.1 Pro (High)"
|
|
|
220
225
|
# Review-receipt identity (AD-038). AW_BRIDGE_VERSION mirrors this bridge's SKILL.md/capability.json
|
|
221
226
|
# version (drift-guarded by agy-review.test.mjs against capability.json).
|
|
222
227
|
AW_RECEIPT_BACKEND="agy"
|
|
223
|
-
AW_BRIDGE_VERSION="
|
|
228
|
+
AW_BRIDGE_VERSION="3.0.0"
|
|
224
229
|
# `-` not `:-` so an EXPLICIT empty AGY_MODEL= survives (drop --model, use settings.json — agy.sh:52).
|
|
225
230
|
AGY_MODEL="${AGY_MODEL-$DEFAULT_AGY_REVIEW_MODEL}"
|
|
226
231
|
# Frontier review models. ANY model is allowed; a sub-frontier one only earns a soft, silenceable warning.
|
|
@@ -541,7 +546,7 @@ case "${1:-}" in
|
|
|
541
546
|
esac
|
|
542
547
|
|
|
543
548
|
usage() {
|
|
544
|
-
echo "usage: $0 code [--facts @f] [--decided @f] [--focus \"…\"] [extra focus…]" >&2
|
|
549
|
+
echo "usage: $0 code [--facts @f] [--ungrounded] [--decided @f] [--focus \"…\"] [extra focus…]" >&2
|
|
545
550
|
echo " $0 plan <plan-file> [--facts @f] [--decided @f] [--focus \"…\"]" >&2
|
|
546
551
|
echo " $0 diff <diff-file> [--facts @f] [--decided @f] [--focus \"…\"]" >&2
|
|
547
552
|
echo " $0 --continue [--decided @f] [--focus \"…\"]" >&2
|
|
@@ -580,6 +585,7 @@ fi
|
|
|
580
585
|
# --- Flag parse (--facts / --decided / --focus + trailing focus) -------------
|
|
581
586
|
FACTS_RAW=""
|
|
582
587
|
DECIDED_RAW=""
|
|
588
|
+
UNGROUNDED=0
|
|
583
589
|
FOCUS_PARTS=()
|
|
584
590
|
# A value-taking flag must be followed by a real value — never end-of-args and never another flag.
|
|
585
591
|
# Otherwise `agy-review code --facts --focus x` would silently take "--focus" as the facts and spend a
|
|
@@ -598,6 +604,12 @@ while [[ $# -gt 0 ]]; do
|
|
|
598
604
|
exit 2
|
|
599
605
|
fi
|
|
600
606
|
need_value "$1" "${2:-}"; FACTS_RAW="$2"; shift 2 ;;
|
|
607
|
+
--ungrounded)
|
|
608
|
+
if [[ -n "$resume_mode" ]]; then
|
|
609
|
+
echo "error: --ungrounded is not valid on a continuation (the original round already set its grounding)." >&2
|
|
610
|
+
exit 2
|
|
611
|
+
fi
|
|
612
|
+
UNGROUNDED=1; shift ;;
|
|
601
613
|
--decided)
|
|
602
614
|
need_value "$1" "${2:-}"; DECIDED_RAW="$2"; shift 2 ;;
|
|
603
615
|
--focus)
|
|
@@ -623,6 +635,18 @@ done
|
|
|
623
635
|
# Merge --focus values and trailing focus words, in parse order, into ONE focus block.
|
|
624
636
|
FOCUS="${FOCUS_PARTS[*]:-}"
|
|
625
637
|
|
|
638
|
+
# --ungrounded closed grammar (D4): code-mode only, and an explicit contradiction with --facts refuses.
|
|
639
|
+
if [[ "$UNGROUNDED" == "1" ]]; then
|
|
640
|
+
if [[ -n "$FACTS_RAW" ]]; then
|
|
641
|
+
echo "error: --ungrounded contradicts --facts — pass the verified facts (grounded) or drop them (--ungrounded), never both." >&2
|
|
642
|
+
exit 2
|
|
643
|
+
fi
|
|
644
|
+
if [[ "$mode" != "code" ]]; then
|
|
645
|
+
echo "error: --ungrounded is only valid in code mode — $mode mode already proceeds ungrounded with a loud warning." >&2
|
|
646
|
+
exit 2
|
|
647
|
+
fi
|
|
648
|
+
fi
|
|
649
|
+
|
|
626
650
|
# Resolve @file / literal for --facts and --decided NOW (cwd = invocation, before any code-mode cd).
|
|
627
651
|
# The `@file` existence check runs at TOP LEVEL (not inside a command substitution) so its exit-2 exits
|
|
628
652
|
# the whole script, not just a subshell.
|
|
@@ -648,6 +672,25 @@ if [[ -n "$DECIDED_RAW" ]]; then
|
|
|
648
672
|
fi
|
|
649
673
|
|
|
650
674
|
if [[ -z "$FACTS_CONTENT" && -z "$resume_mode" ]]; then
|
|
675
|
+
# code mode fails CLOSED before the spend (D4): an ungrounded CODE receipt records grounded:false,
|
|
676
|
+
# which the review-state gate rejects — the run would be paid for and attest nothing. Keyed on the
|
|
677
|
+
# resolved CONTENT, so --facts naming an empty payload refuses identically.
|
|
678
|
+
if [[ "$mode" == "code" && "$UNGROUNDED" != "1" && "$AGY_PROBE" != "1" ]]; then
|
|
679
|
+
# The recovery hint resolves the kit's grounding tool from THIS wrapper's location (monorepo
|
|
680
|
+
# canon / deployed skills sibling / kit-bundled mirror) — a repo-relative path would not exist
|
|
681
|
+
# for a globally installed kit. Quoted: an install path may carry spaces.
|
|
682
|
+
grounding_tool="node <agent-workflow-kit>/tools/grounding.mjs"
|
|
683
|
+
for _g in "$HERE/../../agent-workflow-kit/tools/grounding.mjs" "$HERE/../../../tools/grounding.mjs"; do
|
|
684
|
+
if [[ -f "$_g" ]]; then grounding_tool="node \"$_g\""; break; fi
|
|
685
|
+
done
|
|
686
|
+
echo "error: 'agy-review code' requires grounded facts and refuses BEFORE spending a run — an" >&2
|
|
687
|
+
echo " ungrounded code review GUESSES, and its receipt (grounded:false) never attests." >&2
|
|
688
|
+
echo " Assemble the verified facts, then re-run:" >&2
|
|
689
|
+
echo " $grounding_tool --constraints [--plan <plan-file>] --out <facts-file>" >&2
|
|
690
|
+
echo " agy-review code --facts @<facts-file>" >&2
|
|
691
|
+
echo " Explicit escapes: --ungrounded (throwaway opinion) · AGY_PROBE=1 (a probe never attests)." >&2
|
|
692
|
+
exit 2
|
|
693
|
+
fi
|
|
651
694
|
echo "warning: no --facts supplied. agy reads NOTHING by default, so an ungrounded review GUESSES" >&2
|
|
652
695
|
echo " (stale-model and partial-diff false positives). Pass --facts @file with the verified" >&2
|
|
653
696
|
echo " facts the model must review AGAINST. Proceeding without grounding." >&2
|
|
@@ -190,17 +190,100 @@ describe('agy-review.sh — guard + grounding (2, 3)', () => {
|
|
|
190
190
|
assert.match(r.prompt, /## Focus\nfirst second third/);
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
-
it('
|
|
193
|
+
it('plan mode with no --facts keeps the warning and proceeds (unchanged contract)', () => {
|
|
194
194
|
const sb = makeSandbox();
|
|
195
|
-
|
|
195
|
+
writeFileSync(join(sb.repo, 'p.md'), '# plan body\n');
|
|
196
|
+
const r = run(sb, { args: ['plan', 'p.md'] });
|
|
196
197
|
rmSync(sb.home, { recursive: true, force: true });
|
|
197
198
|
assert.equal(r.status, 0, r.stderr);
|
|
198
199
|
assert.match(r.stderr, /no --facts supplied/);
|
|
199
|
-
assert.equal(r.invoked, true, 'an ungrounded review still proceeds (warn, not block)');
|
|
200
|
+
assert.equal(r.invoked, true, 'an ungrounded plan review still proceeds (warn, not block)');
|
|
200
201
|
assert.match(r.prompt, /none supplied/, 'the prompt notes the missing facts in-band');
|
|
201
202
|
});
|
|
202
203
|
});
|
|
203
204
|
|
|
205
|
+
// ── code mode fails CLOSED without grounded facts (D4) ───────────────────────────
|
|
206
|
+
// An ungrounded CODE receipt records grounded:false, which the kit's review-state gate rejects —
|
|
207
|
+
// the run would be paid for and attest nothing. The wrapper refuses BEFORE the spend, keyed on the
|
|
208
|
+
// resolved CONTENT (an empty --facts payload refuses identically). Escapes: the explicit
|
|
209
|
+
// --ungrounded flag (throwaway opinion) and AGY_PROBE=1 (a probe receipt never attests anyway).
|
|
210
|
+
describe('agy-review.sh — code mode fails CLOSED without grounded facts (D4)', () => {
|
|
211
|
+
it('code mode with no --facts exits 2 before any agy invocation', () => {
|
|
212
|
+
const sb = makeSandbox();
|
|
213
|
+
const r = run(sb, { args: ['code'] });
|
|
214
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
215
|
+
assert.equal(r.status, 2, r.stderr);
|
|
216
|
+
assert.equal(r.invoked, false, 'the refusal must fire before any agy invocation — zero runs spent');
|
|
217
|
+
assert.match(r.stderr, /grounding\.mjs/, 'the refusal names the facts assembler');
|
|
218
|
+
assert.match(r.stderr, /agy-review code --facts @/, 'the refusal prints the exact re-run line');
|
|
219
|
+
const hint = r.stderr.match(/node "([^"]+grounding\.mjs)"/);
|
|
220
|
+
assert.ok(hint, 'the recovery hint resolves and QUOTES a real grounding.mjs path (an install path may carry spaces)');
|
|
221
|
+
assert.ok(existsSync(hint[1]), 'the resolved hint path exists on this layout');
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('code mode with --facts naming an EMPTY payload exits 2 before any agy invocation', () => {
|
|
225
|
+
const sb = makeSandbox();
|
|
226
|
+
writeFileSync(join(sb.repo, 'empty-facts.md'), '');
|
|
227
|
+
const r = run(sb, { args: ['code', '--facts', '@empty-facts.md'] });
|
|
228
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
229
|
+
assert.equal(r.status, 2, 'the refusal keys on the CONTENT, not the flag');
|
|
230
|
+
assert.equal(r.invoked, false, 'an empty payload must not spend a run');
|
|
231
|
+
assert.match(r.stderr, /agy-review code --facts @/);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('code --ungrounded proceeds and the receipt records grounded:false', () => {
|
|
235
|
+
const sb = makeSandbox();
|
|
236
|
+
const r = run(sb, { args: ['code', '--ungrounded'], env: { AGY_FAKE_OUTPUT: VERDICT_OUTPUT } });
|
|
237
|
+
const receipts = readReceipts(sb.repo);
|
|
238
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
239
|
+
assert.equal(r.status, 0, r.stderr);
|
|
240
|
+
assert.equal(r.invoked, true, 'the explicit escape lets the run proceed');
|
|
241
|
+
assert.equal(receipts.length, 1);
|
|
242
|
+
assert.equal(receipts[0].grounded, false, 'an --ungrounded run still records grounded:false');
|
|
243
|
+
assert.equal(receipts[0].factsHash, null);
|
|
244
|
+
assert.match(r.stderr, /no --facts supplied/, 'the escape path stays loud, never silent');
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('AGY_PROBE=1 code with no --facts proceeds and the receipt records probe:true', () => {
|
|
248
|
+
const sb = makeSandbox();
|
|
249
|
+
const r = run(sb, { args: ['code'], env: { AGY_PROBE: '1', AGY_FAKE_OUTPUT: VERDICT_OUTPUT } });
|
|
250
|
+
const receipts = readReceipts(sb.repo);
|
|
251
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
252
|
+
assert.equal(r.status, 0, r.stderr);
|
|
253
|
+
assert.equal(r.invoked, true, 'an ungrounded probe is coherent — a probe receipt never attests');
|
|
254
|
+
assert.equal(receipts[0].probe, true);
|
|
255
|
+
assert.equal(receipts[0].grounded, false);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('--ungrounded with --facts is a refusal (contradiction)', () => {
|
|
259
|
+
const sb = makeSandbox();
|
|
260
|
+
const r = run(sb, { args: ['code', '--ungrounded', '--facts', 'f'] });
|
|
261
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
262
|
+
assert.equal(r.status, 2);
|
|
263
|
+
assert.equal(r.invoked, false);
|
|
264
|
+
assert.match(r.stderr, /--ungrounded contradicts --facts/);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('--ungrounded outside code mode is a refusal', () => {
|
|
268
|
+
const sb = makeSandbox();
|
|
269
|
+
writeFileSync(join(sb.repo, 'p.md'), '# p\n');
|
|
270
|
+
const r = run(sb, { args: ['plan', 'p.md', '--ungrounded'] });
|
|
271
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
272
|
+
assert.equal(r.status, 2);
|
|
273
|
+
assert.equal(r.invoked, false);
|
|
274
|
+
assert.match(r.stderr, /--ungrounded is only valid in code mode/);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('--ungrounded on a continuation is a refusal', () => {
|
|
278
|
+
const sb = makeSandbox();
|
|
279
|
+
const r = run(sb, { args: ['--continue', '--ungrounded'] });
|
|
280
|
+
rmSync(sb.home, { recursive: true, force: true });
|
|
281
|
+
assert.equal(r.status, 2);
|
|
282
|
+
assert.equal(r.invoked, false);
|
|
283
|
+
assert.match(r.stderr, /--ungrounded is not valid on a continuation/);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
204
287
|
describe('agy-review.sh — code-mode precomputed diff (4, 5, 8)', () => {
|
|
205
288
|
it('assembles repo map + status + untracked CONTENTS', () => {
|
|
206
289
|
const sb = makeSandbox();
|
|
@@ -754,7 +837,12 @@ describe('agy-review.sh — declared contract is really accepted (forward guard)
|
|
|
754
837
|
for (const descriptor of REVIEW_CONTRACT.flags) {
|
|
755
838
|
const flag = leadingFlag(descriptor);
|
|
756
839
|
const sb = makeSandbox();
|
|
757
|
-
|
|
840
|
+
// D4: code mode refuses without grounded facts, so a non-facts value flag is driven on a
|
|
841
|
+
// grounded run; --ungrounded takes no value, contradicts --facts, and is driven alone.
|
|
842
|
+
const args = flag === '--facts' ? ['code', '--facts', 'f']
|
|
843
|
+
: flag === '--ungrounded' ? ['code', '--ungrounded']
|
|
844
|
+
: ['code', '--facts', 'f', flag, 'f'];
|
|
845
|
+
const r = run(sb, { args });
|
|
758
846
|
rmSync(sb.home, { recursive: true, force: true });
|
|
759
847
|
assert.equal(r.status, 0, `${flag}: ${r.stderr}`);
|
|
760
848
|
}
|
|
@@ -853,9 +941,9 @@ describe('agy-review.sh — review receipts (AD-038)', () => {
|
|
|
853
941
|
assert.equal(receipts[0].probe, true, 'both write paths carry the marker — no unmarked probe lane');
|
|
854
942
|
});
|
|
855
943
|
|
|
856
|
-
it('an ungrounded fresh run records grounded:false + factsHash null (the vacuous-grounding hole stays visible)', () => {
|
|
944
|
+
it('an --ungrounded fresh run records grounded:false + factsHash null (the vacuous-grounding hole stays visible)', () => {
|
|
857
945
|
const sb = makeSandbox();
|
|
858
|
-
const r = run(sb, { args: ['code'], env: { AGY_FAKE_OUTPUT: VERDICT_OUTPUT } });
|
|
946
|
+
const r = run(sb, { args: ['code', '--ungrounded'], env: { AGY_FAKE_OUTPUT: VERDICT_OUTPUT } });
|
|
859
947
|
const receipts = readReceipts(sb.repo);
|
|
860
948
|
rmSync(sb.home, { recursive: true, force: true });
|
|
861
949
|
assert.equal(r.status, 0, r.stderr);
|
|
@@ -863,16 +951,15 @@ describe('agy-review.sh — review receipts (AD-038)', () => {
|
|
|
863
951
|
assert.equal(receipts[0].factsHash, null);
|
|
864
952
|
});
|
|
865
953
|
|
|
866
|
-
it('an EMPTY --facts file
|
|
954
|
+
it('an EMPTY --facts file in code mode refuses pre-spend — no run, no receipt (D4 fail-closed)', () => {
|
|
867
955
|
const sb = makeSandbox();
|
|
868
956
|
writeFileSync(join(sb.home, 'empty-facts.md'), '');
|
|
869
957
|
const r = run(sb, { args: ['code', '--facts', `@${join(sb.home, 'empty-facts.md')}`], env: { AGY_FAKE_OUTPUT: VERDICT_OUTPUT } });
|
|
870
958
|
const receipts = readReceipts(sb.repo);
|
|
871
959
|
rmSync(sb.home, { recursive: true, force: true });
|
|
872
|
-
assert.equal(r.status,
|
|
873
|
-
assert.equal(
|
|
874
|
-
assert.equal(receipts
|
|
875
|
-
assert.match(r.stderr, /no --facts supplied|ungrounded review GUESSES/, 'the ungrounded warning fires for an empty payload');
|
|
960
|
+
assert.equal(r.status, 2, 'vacuous grounding no longer spends a run');
|
|
961
|
+
assert.equal(r.invoked, false);
|
|
962
|
+
assert.equal(receipts.length, 0, 'no run — no receipt');
|
|
876
963
|
});
|
|
877
964
|
|
|
878
965
|
it('parses REWORK and plain SHIP; records "unknown" when the mandated section is absent', () => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"schema": 1,
|
|
4
4
|
"name": "antigravity-cli-bridge",
|
|
5
5
|
"kind": "execution-backend",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "3.0.0",
|
|
7
7
|
"provides": ["review", "probe"],
|
|
8
8
|
"roles": {
|
|
9
9
|
"review": {
|
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
"output": "advisory",
|
|
15
15
|
"contract": {
|
|
16
16
|
"invocations": [
|
|
17
|
-
"agy-review code [--facts @f] [--decided @f] [--focus \"…\"] [extra focus…]",
|
|
17
|
+
"agy-review code [--facts @f] [--ungrounded] [--decided @f] [--focus \"…\"] [extra focus…]",
|
|
18
18
|
"agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus \"…\"]",
|
|
19
19
|
"agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus \"…\"]"
|
|
20
20
|
],
|
|
21
|
-
"grounding": "grounded review — agy reads NOTHING by default, an ungrounded review GUESSES: --facts @f = the verified facts to review AGAINST; --decided @f = decisions already made, do NOT re-raise (anti-circling)",
|
|
21
|
+
"grounding": "grounded review — agy reads NOTHING by default, an ungrounded review GUESSES: --facts @f = the verified facts to review AGAINST; --decided @f = decisions already made, do NOT re-raise (anti-circling). code mode REQUIRES a non-empty --facts payload and refuses BEFORE spending a run (escapes: --ungrounded, AGY_PROBE=1); plan/diff proceed with a loud warning",
|
|
22
22
|
"flags": [
|
|
23
|
-
"--facts @f — verified facts the review runs AGAINST (
|
|
23
|
+
"--facts @f — verified facts the review runs AGAINST (code mode REQUIRES a non-empty payload; plan/diff warn loudly when omitted)",
|
|
24
|
+
"--ungrounded — deliberately ungrounded CODE review, a throwaway opinion (code mode only, contradicts --facts; the receipt records grounded:false and never attests)",
|
|
24
25
|
"--decided @f — already-decided / already-addressed list; do NOT re-raise (anti-circling; the round-2 payload)",
|
|
25
26
|
"--focus \"…\" — extra focus (repeatable; code mode also takes trailing focus words)"
|
|
26
27
|
],
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
"agy-review --continue [--decided @f] [--focus \"…\"]",
|
|
29
30
|
"agy-review --conversation <id> [--decided @f] [--focus \"…\"]"
|
|
30
31
|
],
|
|
31
|
-
"receipt": "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides; plan/diff outside a git tree: warn + skip unless overridden): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK); grounded = whether a NON-EMPTY --facts payload was supplied (an empty payload records grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts payload; a continuation receipt is fresh:false (informational-only — it cannot attest the folded tree); probe = whether the run relaxed the quality guards (AGY_PROBE=1), written on EVERY receipt so it self-declares — the kit's review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review",
|
|
32
|
+
"receipt": "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides; plan/diff outside a git tree: warn + skip unless overridden): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK); grounded = whether a NON-EMPTY --facts payload was supplied (code mode refuses pre-spend without one — no run, no receipt — unless --ungrounded/AGY_PROBE=1; in plan/diff an empty payload records grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts payload; a continuation receipt is fresh:false (informational-only — it cannot attest the folded tree); probe = whether the run relaxed the quality guards (AGY_PROBE=1), written on EVERY receipt so it self-declares — the kit's review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review",
|
|
32
33
|
"notes": [
|
|
33
34
|
"pre-dispatch host-diff: before the FIRST dispatch of this bridge, diff its declared networkHosts against the live sandbox allow-list — a missing host is surfaced to the maintainer BEFORE dispatching, never fired into a known prompt"
|
|
34
35
|
]
|
|
@@ -50,7 +51,8 @@
|
|
|
50
51
|
"whenNotTo": ["a clean tree — the wrapper exits before spending a run"],
|
|
51
52
|
"invocationRefs": [{ "contractField": "invocations", "index": 0 }],
|
|
52
53
|
"operands": [
|
|
53
|
-
{ "slot": "[--facts @f]", "required": false, "description": "the verified facts to review AGAINST;
|
|
54
|
+
{ "slot": "[--facts @f]", "required": false, "description": "the verified facts to review AGAINST; code mode refuses pre-spend without a non-empty payload (escapes: --ungrounded, AGY_PROBE=1)" },
|
|
55
|
+
{ "slot": "[--ungrounded]", "required": false, "description": "deliberately ungrounded code review — a throwaway opinion; the receipt records grounded:false and never attests" },
|
|
54
56
|
{ "slot": "[--decided @f]", "required": false, "description": "decisions already made; the reviewer must not re-raise them (anti-circling)" },
|
|
55
57
|
{ "slot": "[--focus \"…\"]", "required": false, "description": "what this review must look at (repeatable)" },
|
|
56
58
|
{ "slot": "[extra focus…]", "required": false, "description": "extra focus words appended to the review directive" }
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
{ "value": "read-only posture — the prompt forbids edits, commands and git writes", "enforcement": "advisory", "source": "bin/agy-review.sh" },
|
|
60
62
|
{ "value": "receives no ambient repo/file context by default — the wrapper passes no --add-dir", "enforcement": "enforced", "source": "bin/agy-review.sh" },
|
|
61
63
|
{ "value": "an ungrounded review guesses — stale-model and partial-diff false positives", "enforcement": "advisory", "source": "bin/agy-review.sh" },
|
|
64
|
+
{ "value": "without a non-empty --facts payload the run refuses BEFORE the spend (exit 2) — the only escapes are --ungrounded and AGY_PROBE=1", "enforcement": "enforced", "source": "bin/agy-review.sh" },
|
|
62
65
|
{ "value": "an ungrounded run records grounded:false and the review-state gate rejects it", "enforcement": "enforced", "source": "capability.json roles.review.contract.receipt" },
|
|
63
66
|
{ "value": "an oversized prompt refuses rather than truncate", "enforcement": "enforced", "condition": "unless AGY_REVIEW_ALLOW_ADDDIR=1 offloads it to a private --add-dir staging dir", "source": "capability.json settings.AGY_REVIEW_ALLOW_ADDDIR" }
|
|
64
67
|
],
|
|
@@ -185,9 +188,9 @@
|
|
|
185
188
|
"deliberately reviewing with a cheaper non-frontier model"
|
|
186
189
|
],
|
|
187
190
|
"whenNotTo": ["any run whose output informs what ships — a probe never attests"],
|
|
188
|
-
"descriptor": "AGY_PROBE=1 agy-review code --facts @<facts-file>",
|
|
191
|
+
"descriptor": "AGY_PROBE=1 agy-review code [--facts @<facts-file>]",
|
|
189
192
|
"operands": [
|
|
190
|
-
{ "slot": "@<facts-file>", "required":
|
|
193
|
+
{ "slot": "[--facts @<facts-file>]", "required": false, "description": "the verified facts the review runs AGAINST — a probe may run ungrounded (its receipt never attests either way)" }
|
|
191
194
|
],
|
|
192
195
|
"guardrails": [
|
|
193
196
|
{ "value": "a probe review mints a probe-marked receipt the review-state gate rejects", "enforcement": "enforced", "source": "agent-workflow-kit tools/review-state.mjs" }
|
|
@@ -58,13 +58,17 @@ prompt for `agy-run`. It **mechanizes the grounded-review contract** (see
|
|
|
58
58
|
[`review-prompt.md`](./review-prompt.md)) so grounding is the enforced default, not a per-call effort:
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
agy-review code
|
|
62
|
-
agy-review
|
|
61
|
+
agy-review code --facts @facts.md [--decided @decided.md] [--focus "…"] [extra focus…] # facts REQUIRED — refuses pre-spend
|
|
62
|
+
agy-review code --ungrounded # explicit escape: throwaway ungrounded opinion (never attests)
|
|
63
|
+
agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus "…"] # no facts ⇒ loud warning, proceeds
|
|
63
64
|
agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus "…"]
|
|
64
65
|
agy-review --continue [--decided @f] [--focus "…"] # round-2 delta — no re-assembly
|
|
65
66
|
agy-review --conversation <id> [--decided @f] [--focus "…"]
|
|
66
67
|
```
|
|
67
68
|
|
|
69
|
+
`code` fails CLOSED without a non-empty `--facts` payload — the refusal fires before any run is
|
|
70
|
+
spent; the explicit escapes are `--ungrounded` and `AGY_PROBE=1` (a probe never attests).
|
|
71
|
+
|
|
68
72
|
What it does for you, and what YOU must supply:
|
|
69
73
|
|
|
70
74
|
- **It** assembles POSTURE + a model/cutoff GUARD + your facts + your already-decided list + your focus
|
|
@@ -48,14 +48,15 @@ subscription invariant, and the byte ceiling all apply once. The playbook is in
|
|
|
48
48
|
[`driving-agy.md`](./driving-agy.md); the surface:
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
agy-review code
|
|
51
|
+
agy-review code --facts @f [--decided @f] [--focus "…"] # facts REQUIRED — refuses pre-spend (escapes: --ungrounded, AGY_PROBE=1)
|
|
52
|
+
agy-review plan <file>|diff <file> [--facts @f] [--decided @f] [--focus "…"]
|
|
52
53
|
agy-review --continue | --conversation <id> [--decided @f] [--focus "…"] # round-2 delta
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
| Var | Default | Effect |
|
|
56
57
|
|---|---|---|
|
|
57
58
|
| `AGY_MODEL` | `Gemini 3.1 Pro (High)` | frontier default; **any** model is allowed — a sub-frontier one earns a silenceable advisory (quality-first, not a gate) |
|
|
58
|
-
| `AGY_PROBE` | `0` | `1` silences the off-frontier model advisory (
|
|
59
|
+
| `AGY_PROBE` | `0` | `1` silences the off-frontier model advisory AND lets `code` run without `--facts` (an ungrounded probe never attests — its receipt is probe-marked) |
|
|
59
60
|
| `AGY_REVIEW_ALLOW_ADDDIR` | `0` | `1` lets an oversized `code` review offload ONLY the change set to a private staging dir via `--add-dir` (the grounding stays inline; re-enables the Issue-001 stall risk — prefer splitting into focused reviews) |
|
|
60
61
|
| `AGY_HARD_TIMEOUT` | `30m` | the review's hard cap (longer default than a probe — reviews are slower) |
|
|
61
62
|
| `AGY_MAX_PROMPT_BYTES` | `120000` | the same single-argv byte ceiling; oversized → trim/split (or the `--add-dir` escape above) |
|
|
@@ -23,7 +23,7 @@ GUARD Do NOT comment on AI model names/versions or your own knowledge cutoff
|
|
|
23
23
|
and a known source of false positives. Review ONLY the engineering, AGAINST the facts.
|
|
24
24
|
|
|
25
25
|
## Grounded facts — review AGAINST these, do NOT guess the code
|
|
26
|
-
{{GROUNDED_FACTS}} # from --facts @file (omitted -> an in-band note + a LOUD stderr warning)
|
|
26
|
+
{{GROUNDED_FACTS}} # from --facts @file (code: REQUIRED non-empty, refuses pre-spend — escapes --ungrounded / AGY_PROBE=1; plan/diff omitted -> an in-band note + a LOUD stderr warning)
|
|
27
27
|
|
|
28
28
|
## Decisions already made / already addressed — do NOT re-raise these
|
|
29
29
|
{{ALREADY_DECIDED}} # from --decided @file (optional — the anti-circling lever; the round-2 payload)
|
package/capability.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -110,13 +110,14 @@ const RAW_BACKENDS = [
|
|
|
110
110
|
roleContracts: {
|
|
111
111
|
review: {
|
|
112
112
|
invocations: [
|
|
113
|
-
'agy-review code [--facts @f] [--decided @f] [--focus "…"] [extra focus…]',
|
|
113
|
+
'agy-review code [--facts @f] [--ungrounded] [--decided @f] [--focus "…"] [extra focus…]',
|
|
114
114
|
'agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus "…"]',
|
|
115
115
|
'agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus "…"]',
|
|
116
116
|
],
|
|
117
|
-
grounding: 'grounded review — agy reads NOTHING by default, an ungrounded review GUESSES: --facts @f = the verified facts to review AGAINST; --decided @f = decisions already made, do NOT re-raise (anti-circling)',
|
|
117
|
+
grounding: 'grounded review — agy reads NOTHING by default, an ungrounded review GUESSES: --facts @f = the verified facts to review AGAINST; --decided @f = decisions already made, do NOT re-raise (anti-circling). code mode REQUIRES a non-empty --facts payload and refuses BEFORE spending a run (escapes: --ungrounded, AGY_PROBE=1); plan/diff proceed with a loud warning',
|
|
118
118
|
flags: [
|
|
119
|
-
'--facts @f — verified facts the review runs AGAINST (
|
|
119
|
+
'--facts @f — verified facts the review runs AGAINST (code mode REQUIRES a non-empty payload; plan/diff warn loudly when omitted)',
|
|
120
|
+
'--ungrounded — deliberately ungrounded CODE review, a throwaway opinion (code mode only, contradicts --facts; the receipt records grounded:false and never attests)',
|
|
120
121
|
'--decided @f — already-decided / already-addressed list; do NOT re-raise (anti-circling; the round-2 payload)',
|
|
121
122
|
'--focus "…" — extra focus (repeatable; code mode also takes trailing focus words)',
|
|
122
123
|
],
|
|
@@ -124,7 +125,7 @@ const RAW_BACKENDS = [
|
|
|
124
125
|
'agy-review --continue [--decided @f] [--focus "…"]',
|
|
125
126
|
'agy-review --conversation <id> [--decided @f] [--focus "…"]',
|
|
126
127
|
],
|
|
127
|
-
receipt: "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides; plan/diff outside a git tree: warn + skip unless overridden): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK); grounded = whether a NON-EMPTY --facts payload was supplied (an empty payload records grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts payload; a continuation receipt is fresh:false (informational-only — it cannot attest the folded tree); probe = whether the run relaxed the quality guards (AGY_PROBE=1), written on EVERY receipt so it self-declares — the kit's review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review",
|
|
128
|
+
receipt: "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides; plan/diff outside a git tree: warn + skip unless overridden): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK); grounded = whether a NON-EMPTY --facts payload was supplied (code mode refuses pre-spend without one — no run, no receipt — unless --ungrounded/AGY_PROBE=1; in plan/diff an empty payload records grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts payload; a continuation receipt is fresh:false (informational-only — it cannot attest the folded tree); probe = whether the run relaxed the quality guards (AGY_PROBE=1), written on EVERY receipt so it self-declares — the kit's review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review",
|
|
128
129
|
notes: [
|
|
129
130
|
'pre-dispatch host-diff: before the FIRST dispatch of this bridge, diff its declared networkHosts against the live sandbox allow-list — a missing host is surfaced to the maintainer BEFORE dispatching, never fired into a known prompt',
|
|
130
131
|
],
|