@sabaiway/agent-workflow-kit 1.20.0 → 1.22.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.
@@ -51,6 +51,41 @@ agy-run "Continue from the prior architecture critique; focus on test gaps." --
51
51
  Use conversation state only when it saves quota or preserves useful context. For auditable decisions,
52
52
  prefer self-contained prompts.
53
53
 
54
+ ## Review via `agy-review` (grounded second opinion)
55
+
56
+ For a code / plan / diff review, drive the dedicated **`agy-review`** wrapper rather than hand-rolling a
57
+ prompt for `agy-run`. It **mechanizes the grounded-review contract** (see
58
+ [`review-prompt.md`](./review-prompt.md)) so grounding is the enforced default, not a per-call effort:
59
+
60
+ ```bash
61
+ agy-review code [--facts @facts.md] [--decided @decided.md] [--focus "…"] [extra focus…]
62
+ agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus "…"]
63
+ agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus "…"]
64
+ agy-review --continue [--decided @f] [--focus "…"] # round-2 delta — no re-assembly
65
+ agy-review --conversation <id> [--decided @f] [--focus "…"]
66
+ ```
67
+
68
+ What it does for you, and what YOU must supply:
69
+
70
+ - **It** assembles POSTURE + a model/cutoff GUARD + your facts + your already-decided list + your focus
71
+ + the artifact (in `code` mode, the **repo-complete** working-tree change set) + a strict output
72
+ SHAPE, then delegates execution to `agy-run` (so the hard timeout, the subscription invariant, and
73
+ the single-argv byte ceiling apply once).
74
+ - **You** supply what a script can't generate: `--facts @file` (the **verified facts** the model must
75
+ review AGAINST — agy reads nothing by default, so without this it guesses), `--decided @file` (the
76
+ **anti-circling** list of things already handled — the round-2 payload), and `--focus`.
77
+ - **Anti-circling round 2:** after folding round 1, iterate with `agy-review --continue --decided
78
+ @round1-decisions.md --focus "only the still-open items"`. The continuation sends a small DELTA
79
+ (restated posture + new focus + the output shape + the decided list) and never re-sends the artifact
80
+ — `agy` holds it in the conversation.
81
+ - **Oversized `code` review:** the byte ceiling (`AGY_MAX_PROMPT_BYTES`, default 120000) trips with
82
+ trim/split guidance. `AGY_REVIEW_ALLOW_ADDDIR=1` offloads ONLY the change set to a private staging
83
+ dir and passes it via `--add-dir` (the grounding stays inline) — this re-enables the Issue-001 stall
84
+ risk, bounded by the hard timeout; prefer splitting into focused per-area reviews.
85
+ - **Model:** frontier default `Gemini 3.1 Pro (High)`; any model is allowed (a sub-frontier one earns a
86
+ silenceable `AGY_PROBE=1` advisory). The service can still **stall on large/substantive prompts**
87
+ (Issue-001) — keep reviews **focused**; the hard timeout is the guard.
88
+
54
89
  ## Escalation policy (edits, network, git)
55
90
 
56
91
  The wrapper passes no `--add-dir`, no `--dangerously-skip-permissions`, and no `--sandbox`. Treat this
@@ -70,7 +105,8 @@ rewrite history. Return findings and suggested changes only.
70
105
 
71
106
  ## Project-context prompts
72
107
 
73
- Probe reachability from a project root (cheap model):
108
+ Probe **reachability** from a project root (cheap model) — this is the one place `agy` reading its cwd
109
+ context file is the point of the prompt:
74
110
 
75
111
  ```bash
76
112
  AGY_MODEL="Gemini 3.5 Flash (Low)" agy-run \
@@ -79,24 +115,12 @@ AGY_MODEL="Gemini 3.5 Flash (Low)" agy-run \
79
115
  "Without using a file pointer, is there a project-specific planning skill in this repo? Name it and cite its path."
80
116
  ```
81
117
 
82
- Plan-review prompt shape:
83
-
84
- ```text
85
- You are reviewing the plan below from the current repository root.
86
- Use the root context file and per-workspace skills if they are reachable.
87
- Do not edit files. Do not run git write commands.
88
- Return: 1) blocking issues 2) non-blocking risks 3) missing verification 4) a concise recommendation.
89
- The implementation plan text follows in this same prompt.
90
- ```
91
-
92
- Diff/code-review prompt shape (provide the diff as text):
93
-
94
- ```text
95
- Review this diff against the stated constraints.
96
- Focus on bugs, behavioural regressions, missing tests, and violations of the project rules.
97
- Cite file paths and line hints from the diff where possible. Do not summarise unless there are no findings.
98
- The project constraints and diff text follow in this same prompt.
99
- ```
118
+ **For an actual review, do NOT hand-roll a prompt that tells `agy` to "use the root context file if
119
+ reachable"** — that is the documented root cause of guessing (`agy` cannot reliably read the repo code
120
+ or the diff without an explicit `--add-dir`). Use **`agy-review`** (above): it makes the review
121
+ **self-contained via `--facts`** plus the assembled artifact, so the review never *depends* on `agy`
122
+ reading anything. `agy` may still surface the single cwd context file, but the grounded contract does
123
+ not rely on it.
100
124
 
101
125
  ## Handling output
102
126
 
@@ -1,13 +1,13 @@
1
1
  # `agy` models & flags (reference)
2
2
 
3
3
  The source of truth is the live binary: `agy --version`, `agy --help`, `agy models`. The tables below
4
- were captured from **v1.0.10**; if the binary disagrees, the binary wins. The wrapper command is
4
+ were captured from **v1.0.13**; if the binary disagrees, the binary wins. The wrapper command is
5
5
  `agy-run`, backed by `bin/agy.sh`.
6
6
 
7
7
  ## Headless behaviour
8
8
 
9
9
  Use `-p`, `--print`, or `--prompt` to run one non-interactive prompt and print the text response. The
10
- wrapper always uses headless `-p`. **There is no JSON output mode in v1.0.10** — ask for Markdown,
10
+ wrapper always uses headless `-p`. **There is no JSON output mode in v1.0.13** — ask for Markdown,
11
11
  bullets, tables, or fenced blocks when the caller needs structure, then validate the text yourself.
12
12
 
13
13
  ## Wrapper contract
@@ -32,11 +32,38 @@ Environment:
32
32
  |---|---|---|
33
33
  | `AGY_MODEL` | `Gemini 3.1 Pro (High)` | model display string; set empty (`AGY_MODEL=`) to drop `--model` and let `agy` use `settings.json` |
34
34
  | `AGY_TIMEOUT` | `5m` | value passed to `--print-timeout` |
35
+ | `AGY_HARD_TIMEOUT` | `= AGY_TIMEOUT` | hard `timeout(1)` wall-clock cap (a duration string) |
36
+ | `AGY_MAX_PROMPT_BYTES` | `120000` | single-argv byte ceiling. `agy` takes the prompt as ONE `-p` argv; past `MAX_ARG_STRLEN` (~131072) `execve` fails with a cryptic `Argument list too long`. The wrapper measures the resolved `-`/`@file` prompt and fails loud over the ceiling. A huge **literal** `agy-run "<huge>"` fails at the wrapper's own `exec`, so route large prompts via `-`/`@file`. |
35
37
 
36
38
  Subscription invariant: the wrapper prepends `$HOME/.local/bin` to `PATH` and clears
37
39
  `ANTIGRAVITY_API_KEY` / `GEMINI_API_KEY` / `GOOGLE_API_KEY` / `GOOGLE_GENAI_API_KEY` before execution.
38
40
  Auth comes from the user's cached OAuth token, never from bundled credentials.
39
41
 
42
+ ## `agy-review` contract (review role)
43
+
44
+ For a code / plan / diff review, drive **`agy-review`** (backed by `bin/agy-review.sh`) instead of
45
+ hand-rolling an `agy-run` prompt. It mechanizes the **grounded-review contract** (see
46
+ [`review-prompt.md`](./review-prompt.md)) and delegates execution to `agy-run`, so the timeout, the
47
+ subscription invariant, and the byte ceiling all apply once. The playbook is in
48
+ [`driving-agy.md`](./driving-agy.md); the surface:
49
+
50
+ ```bash
51
+ agy-review code|plan <file>|diff <file> [--facts @f] [--decided @f] [--focus "…"]
52
+ agy-review --continue | --conversation <id> [--decided @f] [--focus "…"] # round-2 delta
53
+ ```
54
+
55
+ | Var | Default | Effect |
56
+ |---|---|---|
57
+ | `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 (throwaway probe) |
59
+ | `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
+ | `AGY_HARD_TIMEOUT` | `30m` | the review's hard cap (longer default than a probe — reviews are slower) |
61
+ | `AGY_MAX_PROMPT_BYTES` | `120000` | the same single-argv byte ceiling; oversized → trim/split (or the `--add-dir` escape above) |
62
+
63
+ `agy-review` is **read-only** and **advisory**: it never edits, commits, or passes a stray `--`
64
+ passthrough (it owns the posture). The service can still **stall on large/substantive prompts**
65
+ (Issue-001) regardless of `--add-dir`, so keep reviews **focused**; the hard timeout is the guard.
66
+
40
67
  ## Models
41
68
 
42
69
  Pass the **exact display string** from `agy models`, or set `AGY_MODEL`.
@@ -59,7 +86,7 @@ AGY_MODEL="Gemini 3.5 Flash (Medium)" agy-run "Read AGENTS.md and report one Har
59
86
  AGY_MODEL="Claude Sonnet 4.6 (Thinking)" AGY_TIMEOUT=10m agy-run @review-prompt.md
60
87
  ```
61
88
 
62
- ## Flags (from `agy --help`, v1.0.10)
89
+ ## Flags (from `agy --help`, v1.0.13)
63
90
 
64
91
  | Flag | Meaning | Notes |
65
92
  |---|---|---|
@@ -74,11 +101,11 @@ AGY_MODEL="Claude Sonnet 4.6 (Thinking)" AGY_TIMEOUT=10m agy-run @review-prompt.
74
101
  | `--sandbox` | run with terminal restrictions enabled | prefer when delegating a prompt that might trigger tool/terminal work |
75
102
  | `--log-file <path>` | override the CLI log-file path | keep logs secret-free and out of committed artifacts |
76
103
 
77
- ## Subcommands (v1.0.10)
104
+ ## Subcommands (v1.0.13)
78
105
 
79
106
  `changelog`, `help`, `install`, `models`, `plugin` / `plugins`, `update`.
80
107
 
81
- **Not available in v1.0.10:** any JSON output mode, and any `agy inspect`. Output is plain text.
108
+ **Not available in v1.0.13:** any JSON output mode, and any `agy inspect`. Output is plain text.
82
109
 
83
110
  ## Project-context flags
84
111
 
@@ -91,3 +118,7 @@ AGY_MODEL="Claude Sonnet 4.6 (Thinking)" AGY_TIMEOUT=10m agy-run @review-prompt.
91
118
 
92
119
  Use `--add-dir` for extra directories not already reachable from cwd. Subdirectory `CLAUDE.md` files
93
120
  are **not** auto-loaded — include those local rules manually in the prompt when they matter.
121
+
122
+ This is **reachability only** — `agy` may *surface* the single cwd context file, but it does **not**
123
+ read your repo code or a diff without an explicit `--add-dir`. So a **review must be self-contained**:
124
+ ground it with `agy-review --facts @file` (above), never by relying on `agy` to read the change set.
@@ -1,51 +1,59 @@
1
- # Review prompt template — `agy-run` (review role)
1
+ # Grounded review contract — `agy-review` (review role)
2
2
 
3
3
  The `review` role of `antigravity-cli-bridge` delegates a **read-only second opinion** to `agy`.
4
- `agy` cannot see the conversation and (in v1.0.10) has no JSON output, so the prompt must be
5
- **self-contained** and ask for **plain-Markdown findings only** no repo edits, no git writes.
6
- Fill the `{{…}}` slots, pipe it to `agy-run`, then verify every finding locally before acting.
4
+ `agy` reads **nothing** by default and its training predates the current codebase, so an *ungrounded*
5
+ review **guesses** stale-model false positives ("that model can't exist") and partial-diff false
6
+ positives ("the bridge code is missing"). The fix is the **agy analog of codex's precomputed diff**:
7
+ feed `agy` a **self-contained** prompt of **verified facts** plus the **full artifact**, and forbid it
8
+ from opining on model names / its own cutoff.
9
+
10
+ > **This file is a STATIC, human-readable reference of the assembled contract — NOT a dynamically
11
+ > rendered template.** `bin/agy-review.sh` assembles the prompt **in code**; the `{{…}}` below are
12
+ > documentation placeholders, not runtime substitutions. The **wrapper is the executable source of
13
+ > truth** — if it disagrees with this file, the wrapper wins (no drift). Drive it through `agy-review`
14
+ > (see [`driving-agy.md`](./driving-agy.md)), supplying `--facts` / `--decided` / `--focus`.
15
+
16
+ ## Assembled prompt shape (byte-stable order)
7
17
 
8
18
  ```text
9
- You are a meticulous staff-level reviewer giving a SECOND OPINION. You are read-only:
10
- do not propose to edit files, run commands, or make git changes — return findings only.
19
+ POSTURE You are a meticulous staff-level engineer giving a read-only SECOND OPINION. Read-only:
20
+ do NOT propose edits, run commands, or make git changes — findings ONLY, advisory.
21
+
22
+ GUARD Do NOT comment on AI model names/versions or your own knowledge cutoff — irrelevant here
23
+ and a known source of false positives. Review ONLY the engineering, AGAINST the facts.
11
24
 
12
- ## What to review
13
- {{TARGET}} # e.g. "the implementation plan below" or "the working-tree diff below"
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)
14
27
 
15
- ## Project rules
16
- Read the repo's root AGENTS.md (your cwd) and obey its Hard Constraints and conventions.
17
- If AGENTS.md declares a verification/gate set, judge the change against it; if it declares
18
- none, say so — do NOT invent checks.
28
+ ## Decisions already made / already addressed — do NOT re-raise these
29
+ {{ALREADY_DECIDED}} # from --decided @file (optional the anti-circling lever; the round-2 payload)
19
30
 
20
- ## Material
21
- {{CONTENT}} # paste the plan text, or the unified diff, or the file excerpts under review
31
+ ## Focus
32
+ {{FOCUS}} # from --focus "…" + any trailing focus words, merged in parse order (optional)
22
33
 
23
- ## Focus (optional)
24
- {{FOCUS}} # e.g. "correctness of the new reducer", "backward-compat of the stamp takeover"
34
+ ## The change set / plan / diff under review
35
+ {{ARTIFACT}} # code: the assembled, repo-complete working-tree change set (or, when oversized
36
+ # with AGY_REVIEW_ALLOW_ADDDIR=1, a private --add-dir staging file)
37
+ # plan/diff: the supplied file, inlined
25
38
 
26
39
  ## Output — Markdown, this exact shape, nothing else
27
40
  ### Verdict
28
41
  One line: SHIP / SHIP WITH NITS / REWORK, plus a one-sentence reason.
29
42
  ### Blocking
30
- Numbered. Correctness bugs, contract violations, data loss, security. Cite file:line.
31
- Empty? write "none".
43
+ Numbered. Correctness bugs, contract violations, data loss, security. Cite file:line. Empty? "none".
32
44
  ### Non-blocking
33
- Numbered. Simplifications, reuse, naming, missing tests. Cite file:line.
45
+ Numbered. Simplifications, reuse, naming, missing tests. Cite file:line. Empty? "none".
34
46
  ### Questions
35
- Anything ambiguous that changes your verdict if answered.
47
+ Anything ambiguous that would change your verdict if answered.
36
48
  ```
37
49
 
38
- ## Usage
50
+ ## Why no "read the repo's AGENTS.md" instruction
39
51
 
40
- ```bash
41
- # critique a plan
42
- AGY_MODEL="Gemini 3.1 Pro (High)" agy-run @/tmp/review-prompt.filled.md
43
-
44
- # critique the current diff (build the prompt with the diff pasted into {{CONTENT}})
45
- git diff | ... # assemble the filled prompt, then:
46
- agy-run @/tmp/review-prompt.filled.md
47
- ```
52
+ Earlier versions told `agy` to *read the repo's root `AGENTS.md` (your cwd)*. That was the documented
53
+ root cause of guessing: `agy` cannot reliably read repo code or the diff without an explicit
54
+ `--add-dir`, so a review that **depends** on it silently reviews half a picture. The grounded contract
55
+ removes that dependency — everything the model needs is **in the prompt** (`--facts` + the artifact).
56
+ `agy` may still *surface* the single cwd context file, but a review must never **rely** on it.
48
57
 
49
- Treat the result as **advisory** — `agy` output may be incomplete or out of date. The orchestrator
50
- re-runs the project's real gates and owns every accepted change. See
51
- [`driving-agy.md`](./driving-agy.md).
58
+ Treat the result as **advisory** — re-run the project's real gates and verify every finding locally
59
+ before acting.
@@ -9,7 +9,7 @@ works in any project.
9
9
  ```bash
10
10
  curl -fsSL https://antigravity.google/cli/install.sh | bash
11
11
  export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc / ~/.zshrc to persist
12
- agy --version # expect 1.0.10 or newer
12
+ agy --version # expect 1.0.13 or newer
13
13
  ```
14
14
 
15
15
  - The binary is **`agy`** (not `antigravity`); it installs to `~/.local/bin/agy`.
@@ -29,22 +29,27 @@ is **personal** — never copy, commit, package, print, or share that directory
29
29
  needs no API keys and must not be configured with API-key billing; the wrapper unsets every
30
30
  `*_API_KEY` so billing can never silently fall back to pay-as-you-go.
31
31
 
32
- ## 3. Put the wrapper on `PATH` as `agy-run`
32
+ ## 3. Put the wrappers on `PATH` (`agy-run` + `agy-review`)
33
33
 
34
- The skill ships the wrapper at `bin/agy.sh`. Expose it on `PATH` under the stable name `agy-run`
35
- (idempotent; refuses to clobber a non-symlink):
34
+ The skill ships **two** wrappers: `bin/agy.sh` (the `probe` role, exposed as `agy-run`) and
35
+ `bin/agy-review.sh` (the grounded `review` role, exposed as `agy-review`). Expose **both** on `PATH`
36
+ (idempotent; refuses to clobber a non-symlink). The kit's `setup-backends.mjs` does this automatically;
37
+ by hand:
36
38
 
37
39
  ```bash
38
40
  mkdir -p "$HOME/.local/bin"
39
41
  skill_dir="$HOME/.claude/skills/antigravity-cli-bridge" # adjust if installed elsewhere
40
- dst="$HOME/.local/bin/agy-run"
41
- if [ -e "$dst" ] && [ ! -L "$dst" ]; then
42
- echo "STOP: $dst exists and is not a symlink"; exit 1
43
- fi
44
- chmod +x "$skill_dir/bin/agy.sh"
45
- ln -sfn "$skill_dir/bin/agy.sh" "$dst"
42
+ for pair in "agy-run:bin/agy.sh" "agy-review:bin/agy-review.sh"; do
43
+ name="${pair%%:*}"; src="$skill_dir/${pair#*:}"
44
+ dst="$HOME/.local/bin/$name"
45
+ if [ -e "$dst" ] && [ ! -L "$dst" ]; then
46
+ echo "STOP: $dst exists and is not a symlink"; exit 1
47
+ fi
48
+ chmod +x "$src"
49
+ ln -sfn "$src" "$dst"
50
+ done
46
51
  export PATH="$HOME/.local/bin:$PATH"
47
- command -v agy-run
52
+ command -v agy-run agy-review
48
53
  ```
49
54
 
50
55
  ## 4. Smoke test
@@ -54,7 +59,7 @@ agy --version
54
59
  echo "say OK" | agy-run -
55
60
  ```
56
61
 
57
- Expected: the version prints (`1.0.10` or newer), then a short reply containing `OK`. If `agy-run`
62
+ Expected: the version prints (`1.0.13` or newer), then a short reply containing `OK`. If `agy-run`
58
63
  reports `'agy' not found`, fix your `PATH` (step 1). If it asks you to sign in, complete step 2.
59
64
 
60
65
  ## Notes
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-kit",
5
5
  "kind": "composition-root",
6
- "version": "1.20.0",
6
+ "version": "1.22.0",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "1.20.0",
3
+ "version": "1.22.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",
@@ -61,10 +61,17 @@ Before proposing changes or committing, review against:
61
61
  ### 2.4. Quality Gates
62
62
  - Always run type-checker, linter, and all tests before committing.
63
63
 
64
- ### 2.5. Right-altitude & code-grounded (planning + review)
64
+ ### 2.5. Planning, review & process-fidelity invariants
65
+ Apply these when authoring a plan, reviewing, folding a finding, or editing code — the layer read **before any code change**. (Full canon: the project's planning / workflow-methodology + orchestration canon.)
65
66
  - **Fold by code, not prose.** Before folding a code-touching finding into a plan or change, read the cited `file:line` and cite it — a prose fold drifts from the code and seeds the next bug.
66
67
  - **Right altitude.** Pin intent + invariants + acceptance criteria (named tests); leave fine code-mechanics to Execute, where prose cannot diverge from reality.
67
- - **Convergence heuristic.** When a review round keeps finding mechanism issues on a stable architecture, stop refining prose raise the altitude or hand it to Execute. (Full canon: the project's planning methodology / workflow-methodology canon.)
68
+ - **No code-mechanics in the plan.** A Step still carries its exact paths + commands (the plan-structure / self-review canon); the ceiling is on *fold-bred* detail — a review fold must not push fine code-mechanics (`cd`, an env default, a flag) into prose. A fold that needs a mechanic is the trigger to write the test instead.
69
+ - **Test-as-spec.** Fold a code-touching finding into a red→green TEST, not a prose paragraph — the gate is the only deterministic checker; a paragraph cannot self-check.
70
+ - **Characterize-first.** Before editing UNCOVERED code, pin its current behavior in a green test, then edit — any unintended change goes red. Never edit what has no checker; first give it one. Keep edits atomic/reversible; prefer SUBTRACTIVE folds.
71
+ - **Heavy review at the diff.** Plan-review settles architecture only (≤2 rounds, stop at the pre-existing→fold-induced crossover); the exhaustive per-Step review runs against real compiling code + the full suite, where a regression fails a gate immediately.
72
+ - **Convergence bar.** A review loop is CLEAN only when one round returns **0 blockers + 0 majors** from EVERY backend the recipe names (nits + a ship verdict is the stop). Folding ≠ convergence — re-review after folding.
73
+ - **Recipe fidelity.** Council runs every backend the recipe names, **every round**; silently dropping a ready backend for quota/convenience is a forbidden downgrade — an unavailable backend is a LOUD, stated degrade, never a quiet drop.
74
+ - **ExitPlanMode ≠ execute.** A harness "approved — start coding" prompt authorizes the PLAN only; this methodology overrides it. Continue into execution only as a DELIBERATE transition after the plan + cold-start prompt exist, never an implicit slide.
68
75
 
69
76
  ---
70
77
 
@@ -19,7 +19,7 @@
19
19
  // Pure, dependency-injectable (fs/env/validator are deps), dependency-free, Node >= 18. Every fs
20
20
  // probe is wrapped → an explicit `unknown` + reason, never a throw and never a nameless failure.
21
21
 
22
- import { existsSync, statSync, accessSync, realpathSync, readFileSync, constants } from 'node:fs';
22
+ import { existsSync, statSync, accessSync, realpathSync, constants } from 'node:fs';
23
23
  import { join } from 'node:path';
24
24
  import { pathToFileURL } from 'node:url';
25
25
  import os from 'node:os';
@@ -51,10 +51,13 @@ const EXPECTED_KIND = 'execution-backend';
51
51
  // The kit-owned registry: the per-backend facts the detector needs even when a bridge is NOT
52
52
  // installed (no manifest on disk to read). Kept in lockstep with the in-repo manifests by the
53
53
  // drift-guard test. `credential.env: null` → no env override exists (do not invent one).
54
+ // `wrapperCmds` is the EXPECTED deduped roles[].cmd set the CURRENT kit bundles — readiness probes
55
+ // THIS set (not the installed manifest's), so a stale install missing a wrapper surfaces DEGRADED.
54
56
  export const KNOWN_BACKENDS = [
55
57
  {
56
58
  name: 'codex-cli-bridge',
57
59
  installed: { env: 'CODEX_CLI_BRIDGE_DIR', default: '~/.claude/skills/codex-cli-bridge', file: 'SKILL.md' },
60
+ wrapperCmds: ['codex-exec', 'codex-review'],
58
61
  bin: 'codex',
59
62
  credential: { env: 'CODEX_HOME', default: '~/.codex', file: 'auth.json' },
60
63
  setupUrl: 'https://github.com/sabaiway/agent-workflow/blob/main/codex-cli-bridge/setup/README.md',
@@ -66,6 +69,7 @@ export const KNOWN_BACKENDS = [
66
69
  {
67
70
  name: 'antigravity-cli-bridge',
68
71
  installed: { env: 'ANTIGRAVITY_CLI_BRIDGE_DIR', default: '~/.claude/skills/antigravity-cli-bridge', file: 'SKILL.md' },
72
+ wrapperCmds: ['agy-review', 'agy-run'],
69
73
  bin: 'agy',
70
74
  credential: { env: null, default: '~/.gemini/antigravity-cli', file: 'antigravity-oauth-token' },
71
75
  setupUrl: 'https://github.com/sabaiway/agent-workflow/blob/main/antigravity-cli-bridge/setup/README.md',
@@ -154,31 +158,6 @@ export const probeCredential = (entry, deps = {}) => {
154
158
  return { state: probeFile(file, deps), path: file };
155
159
  };
156
160
 
157
- const defaultReadManifest = (skillDir, deps = {}) => {
158
- const read = deps.readFile ?? readFileSync;
159
- try {
160
- return JSON.parse(read(join(skillDir, 'capability.json'), 'utf8'));
161
- } catch {
162
- return null;
163
- }
164
- };
165
-
166
- // The bridge's PATH wrapper names = the deduped `roles[].cmd` set (codex's review + execute roles
167
- // are two cmds; antigravity's review + probe roles share one `agy-run`).
168
- const wrapperCmds = (manifest) => {
169
- const roles = manifest && typeof manifest.roles === 'object' && !Array.isArray(manifest.roles) ? manifest.roles : {};
170
- const seen = new Set();
171
- const out = [];
172
- for (const role of Object.values(roles)) {
173
- const cmd = role && typeof role.cmd === 'string' ? role.cmd : null;
174
- if (cmd && !seen.has(cmd)) {
175
- seen.add(cmd);
176
- out.push(cmd);
177
- }
178
- }
179
- return out;
180
- };
181
-
182
161
  const computeReadiness = (manifestState, cli, credentials, wrappers) => {
183
162
  if (manifestState !== OK) return NEEDS_SKILL;
184
163
  if (cli.state !== PRESENT) return NEEDS_CLI;
@@ -204,7 +183,6 @@ export const detectBackend = (entry, deps = {}) => {
204
183
  return { name: cmd, state: r.state };
205
184
  });
206
185
  const probeCredentialsFn = deps.probeCredentials ?? ((e) => probeCredential(e, deps));
207
- const readManifest = deps.readManifest ?? ((dir) => defaultReadManifest(dir, deps));
208
186
 
209
187
  const resolvedDir = resolveDir({ env: entry.installed.env, default: entry.installed.default }, getenv, home);
210
188
  const markerPresent = probeFile(join(resolvedDir, entry.installed.file), deps) === PRESENT;
@@ -238,7 +216,10 @@ export const detectBackend = (entry, deps = {}) => {
238
216
 
239
217
  const cliProbe = probeCliFn(entry.bin);
240
218
  const credentials = probeCredentialsFn(entry);
241
- const wrappers = isOk ? wrapperCmds(readManifest(resolvedDir)).map(probeWrapperFn) : [];
219
+ // Probe the EXPECTED wrapper set the kit bundles (entry.wrapperCmds), NOT the installed manifest's
220
+ // roles — so a STALE install missing a newer wrapper (e.g. agy-review on a v1.0.0 antigravity) is
221
+ // reported DEGRADED rather than a false "ready N/N". Keeps detectBackend pure (reads only its args).
222
+ const wrappers = isOk ? (entry.wrapperCmds ?? []).map(probeWrapperFn) : [];
242
223
  const readiness = computeReadiness(manifestState, cliProbe, credentials, wrappers);
243
224
 
244
225
  const installed = manifestState !== NOT_INSTALLED;
@@ -57,7 +57,8 @@ export const FAMILY_MEMBERS = [
57
57
  installed: { env: 'ANTIGRAVITY_CLI_BRIDGE_DIR', default: '~/.claude/skills/antigravity-cli-bridge', file: 'SKILL.md' },
58
58
  deployed: null,
59
59
  npm: null,
60
- wrapperCmds: ['agy-run'],
60
+ // review → agy-review, probe → agy-run (first-seen role order in capability.json; bridge 2.0.0).
61
+ wrapperCmds: ['agy-review', 'agy-run'],
61
62
  },
62
63
  ];
63
64
 
package/tools/recipes.mjs CHANGED
@@ -46,11 +46,12 @@ export const BACKEND_META = {
46
46
  [AGY]: {
47
47
  cost: 'subscription',
48
48
  quota: { kind: 'subscription', finite: true },
49
- health: 'Note: the Antigravity service may stall on substantive prompts (Issue-001) prefer codex while it lasts.',
49
+ health: 'Note: grounded agy-review gives a SOUND second opinion (it removes the stale-model/partial-diff false positives) — but the Antigravity service can still stall on substantive prompts (Issue-001), so keep reviews focused and prefer codex for large or latency-sensitive ones.',
50
50
  },
51
51
  };
52
52
 
53
- // Deterministic tie-break order: codex before agy (agy carries the standing health caveat above).
53
+ // Deterministic tie-break order: codex before agy. agy is a sound grounded reviewer now, but codex is
54
+ // the more reliable default for substantive reviews (agy carries the standing service-stall caveat above).
54
55
  const BACKEND_PRIORITY = [CODEX, AGY];
55
56
  const priorityIndex = (name) => {
56
57
  const i = BACKEND_PRIORITY.indexOf(name);
@@ -20,6 +20,7 @@ export const ALLOWLIST = [
20
20
  'codex-review',
21
21
  'antigravity-cli-bridge',
22
22
  'agy-run',
23
+ 'agy-review',
23
24
  'agent-workflow-kit',
24
25
  'agent-workflow-memory',
25
26
  'agent-workflow-engine',