{
  "family": "agent-workflow",
  "schema": 1,
  "name": "antigravity-cli-bridge",
  "kind": "execution-backend",
  "version": "5.4.0",
  "provides": ["review", "probe"],
  "posture": { "model": "Gemini 3.7 Flash (High)" },
  "roles": {
    "review": {
      "cmd": "agy-review",
      "source": "bin/agy-review.sh",
      "template": "references/review-prompt.md",
      "modes": ["code", "plan", "diff"],
      "output": "advisory",
      "contract": {
        "invocations": [
          "agy-review code [--facts @f] [--ungrounded] [--decided @f] [--focus \"…\"] [--nonce <n>] [extra focus…]",
          "agy-review plan <plan-file> [--facts @f] [--decided @f] [--focus \"…\"] [--nonce <n>]",
          "agy-review diff <diff-file> [--facts @f] [--decided @f] [--focus \"…\"] [--nonce <n>]"
        ],
        "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",
        "flags": [
          "--facts @f — verified facts the review runs AGAINST (code mode REQUIRES a non-empty payload; plan/diff warn loudly when omitted)",
          "--ungrounded — deliberately ungrounded CODE review, a throwaway opinion (code mode only, contradicts --facts; the receipt records grounded:false and never attests)",
          "--decided @f — already-decided / already-addressed list; do NOT re-raise (anti-circling; the round-2 payload)",
          "--focus \"…\" — extra focus (repeatable; code mode also takes trailing focus words)",
          "--nonce <n> — the flow dispatch nonce, the plain-argument lane onto the AW_REVIEW_NONCE seam (one seam: flag and a non-empty env must agree; a disagreeing pair refuses pre-spend)"
        ],
        "continue": [
          "agy-review --continue [--decided @f] [--focus \"…\"] [--nonce <n>]",
          "agy-review --conversation <id> [--decided @f] [--focus \"…\"] [--nonce <n>]"
        ],
        "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); posture = the ACTUAL run posture {model} (agy has no tier), written on EVERY receipt (D5) — the gate rejects a receipt with an absent/invalid posture (a pre-D5 wrapper minted it; re-run the review), one stderr banner line states the same posture, an ATTESTING review with AGY_MODEL explicitly emptied refuses pre-spend, and a model string carrying control bytes refuses pre-spend in every mode; delivery = how the change set REACHED the model, currently emitted as 'inline' (the whole set rode one prompt — proven by construction) or 'fed' (a chunked feed whose per-part echo proof verified); REQUIRED on every agy code receipt and its ABSENCE is what stops a pre-fed-lane receipt attesting, while the gate accepts any well-formed declaration rather than a particular value; absent by construction on plan/diff/continuation receipts, which carry no change set; a run whose output carries NO recognized '### Verdict' section — empty output included — exits 4 with NO receipt (D4: a FAILED review to RE-RUN, never a fatal session error); when the dispatch nonce seam is supplied — the AW_REVIEW_NONCE environment value or its plain-argument equivalent --nonce <n> (one seam: the flag assigns the same value; supplying both with different values refuses pre-spend) — under the safe grammar [A-Za-z0-9._-]{1,64} (anything else refuses pre-spend), the wrapper first mints the finding MANIFEST {schema, backend, nonce, fingerprint, findings} beside the receipts file (agent-workflow-finding-manifest-<backend>-<nonce>.json; atomic, no-clobber — a byte-identical rewrite is an idempotent no-op, different bytes refuse loudly) ORDERED before the receipt append — a failed manifest write EXCLUDES the receipt append, so a nonce-supplied dispatch can never land a receipt without its readable manifest; a nonce-less invocation adds NO nonce field and mints NO finding manifest (the existing wrapperVersion field still changes with each bridge release); a write failure warns, never fails the review",
        "notes": [
          "transport: every review dispatch drives the CLI in --output-format json (plus --disable-slash-commands) and the returned envelope is parsed in node (bin/agy-envelope.mjs) — the operator-facing invocations and flags above do NOT change, and on a ZERO exit the wrapper still PRINTS the review text, never JSON. A missing or unreadable envelope on a zero exit is a loud failure with NO receipt, never a downgraded verdict and never a fallback to raw-stdout parsing; a non-zero CLI exit keeps its own code and message, and publishes the captured stdout unchanged from the SINGLE dispatch or the FINAL fed turn (which may therefore be a JSON or partial payload — the envelope is parsed only on a zero exit); an INTERMEDIATE feed turn is the exception, its output stays private (Invariant E) and its failure prints only a named error. Enforced by a PRE-SPEND capability probe, not a version floor: agy --help must advertise --output-format and --disable-slash-commands, node must be >= 22, and bin/agy-envelope.mjs must be present — otherwise the review refuses before any run is spent and names the missing capability",
          "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",
          "the review posture banner appends a banner-only timeout=<duration> field — exactly the duration agy-run hands to timeout(1); the hard-timeout preflight fails CLOSED when no timeout/gtimeout binary exists (the wrapper refuses by name before any CLI run, so an uncapped review run can no longer happen), and the field never enters the receipt posture or the D5 banner↔receipt parity",
          "quote the posture banner verbatim when labeling this dispatch — the banner is the machine-stated posture; a prose re-type drifts"
        ]
      }
    },
    "probe": { "cmd": "agy-run", "source": "bin/agy.sh", "output": "advisory" }
  },
  "modeCatalog": [
    {
      "key": "review.code",
      "kind": "primary",
      "role": "review",
      "submode": "code",
      "purpose": "Review the uncommitted working-tree change set against facts you supply.",
      "whenToUse": [
        "a finished segment heading into its review round",
        "a second opinion on real code before the commit ask"
      ],
      "whenNotTo": ["a clean tree — the wrapper exits before spending a run"],
      "invocationRefs": [{ "contractField": "invocations", "index": 0 }],
      "operands": [
        { "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)" },
        { "slot": "[--ungrounded]", "required": false, "description": "deliberately ungrounded code review — a throwaway opinion; the receipt records grounded:false and never attests" },
        { "slot": "[--decided @f]", "required": false, "description": "decisions already made; the reviewer must not re-raise them (anti-circling)" },
        { "slot": "[--focus \"…\"]", "required": false, "description": "what this review must look at (repeatable)" },
        { "slot": "[--nonce <n>]", "required": false, "description": "the flow dispatch nonce — the plain-argument lane onto the AW_REVIEW_NONCE seam (round-open prints the value; flag and a non-empty env must agree)" },
        { "slot": "[extra focus…]", "required": false, "description": "extra focus words appended to the review directive" }
      ],
      "guardrails": [
        { "value": "read-only posture — the prompt forbids edits, commands and git writes", "enforcement": "advisory", "source": "bin/agy-review.sh" },
        { "value": "receives no ambient repo/file context by default — the wrapper passes no --add-dir", "enforcement": "enforced", "source": "bin/agy-review.sh" },
        { "value": "an ungrounded review guesses — stale-model and partial-diff false positives", "enforcement": "advisory", "source": "bin/agy-review.sh" },
        { "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" },
        { "value": "an ungrounded run records grounded:false and the review-state gate rejects it", "enforcement": "enforced", "source": "capability.json roles.review.contract.receipt" },
        { "value": "an oversized prompt is never truncated", "enforcement": "enforced", "condition": "code mode DELIVERS it as a chunked feed whose per-part delivery proof must verify (a missing or wrong echo exits 4 with no receipt); plan/diff refuse over the cap", "source": "bin/agy-review.sh plan_fed_review + verify_delivery_proof" }
      ],
      "customHooks": ["AGY_PROBE"]
    },
    {
      "key": "review.plan",
      "kind": "primary",
      "role": "review",
      "submode": "plan",
      "purpose": "Critique an implementation plan before any of its code exists.",
      "whenToUse": [
        "a plan draft heading into its review council",
        "checking whether a cold executor could really run the plan"
      ],
      "whenNotTo": ["a working-tree change set — that is review.code"],
      "invocationRefs": [{ "contractField": "invocations", "index": 1 }],
      "operands": [
        { "slot": "<plan-file>", "required": true, "description": "the plan file under review" },
        { "slot": "[--facts @f]", "required": false, "description": "the verified facts to review AGAINST; omitting it warns loudly and records the review ungrounded" },
        { "slot": "[--decided @f]", "required": false, "description": "decisions already made; the reviewer must not re-raise them (anti-circling)" },
        { "slot": "[--focus \"…\"]", "required": false, "description": "what this review must look at (repeatable)" },
        { "slot": "[--nonce <n>]", "required": false, "description": "the flow dispatch nonce — the plain-argument lane onto the AW_REVIEW_NONCE seam (round-open prints the value; flag and a non-empty env must agree)" }
      ],
      "guardrails": [
        { "value": "read-only posture — the prompt forbids edits, commands and git writes", "enforcement": "advisory", "source": "bin/agy-review.sh" },
        { "value": "outside a git tree the receipt is skipped with a warning", "enforcement": "enforced", "condition": "unless AW_REVIEW_RECEIPTS names a destination", "source": "capability.json roles.review.contract.receipt" }
      ],
      "customHooks": ["AGY_PROBE"]
    },
    {
      "key": "review.diff",
      "kind": "primary",
      "role": "review",
      "submode": "diff",
      "purpose": "Review a diff file you assembled yourself, rather than the live working tree.",
      "whenToUse": [
        "reviewing a diff that is not the current tree — a patch, a range, another branch",
        "reviewing a change set trimmed to the hunks that matter"
      ],
      "whenNotTo": ["the current uncommitted tree — review.code assembles that for you"],
      "invocationRefs": [{ "contractField": "invocations", "index": 2 }],
      "operands": [
        { "slot": "<diff-file>", "required": true, "description": "the diff file under review" },
        { "slot": "[--facts @f]", "required": false, "description": "the verified facts to review AGAINST; omitting it warns loudly and records the review ungrounded" },
        { "slot": "[--decided @f]", "required": false, "description": "decisions already made; the reviewer must not re-raise them (anti-circling)" },
        { "slot": "[--focus \"…\"]", "required": false, "description": "what this review must look at (repeatable)" },
        { "slot": "[--nonce <n>]", "required": false, "description": "the flow dispatch nonce — the plain-argument lane onto the AW_REVIEW_NONCE seam (round-open prints the value; flag and a non-empty env must agree)" }
      ],
      "guardrails": [
        { "value": "read-only posture — the prompt forbids edits, commands and git writes", "enforcement": "advisory", "source": "bin/agy-review.sh" },
        { "value": "the receipt fingerprints the DIFF FILE, never the tree — it cannot attest the tree", "enforcement": "enforced", "source": "capability.json roles.review.contract.receipt" }
      ],
      "customHooks": ["AGY_PROBE"]
    },
    {
      "key": "review.continue",
      "kind": "continuation",
      "role": "review",
      "purpose": "Send a round-2 delta into the review already open in this conversation.",
      "whenToUse": [
        "asking the same reviewer whether a fold really solves its own finding",
        "a follow-up round that must not re-read the whole artifact"
      ],
      "whenNotTo": ["attesting a folded tree — a continuation records fresh:false and never satisfies the gate"],
      "invocationRefs": [{ "contractField": "continue", "index": 0 }],
      "operands": [
        { "slot": "[--decided @f]", "required": false, "description": "decisions already made; the reviewer must not re-raise them (anti-circling)" },
        { "slot": "[--focus \"…\"]", "required": false, "description": "what this round must look at (repeatable)" },
        { "slot": "[--nonce <n>]", "required": false, "description": "the flow dispatch nonce — the plain-argument lane onto the AW_REVIEW_NONCE seam (a continuation manifest carries fingerprint null)" }
      ],
      "guardrails": [
        { "value": "--facts is rejected on a continuation — the facts are already in the conversation", "enforcement": "enforced", "source": "bin/agy-review.sh" },
        { "value": "a continuation receipt is fresh:false — informational only, never a gate pass", "enforcement": "enforced", "source": "capability.json roles.review.contract.receipt" }
      ],
      "customHooks": ["AGY_PROBE"]
    },
    {
      "key": "review.conversation",
      "kind": "continuation",
      "role": "review",
      "purpose": "Resume a NAMED review conversation by its id, rather than the most recent one.",
      "whenToUse": ["returning to a specific earlier review after other agy runs happened in between"],
      "invocationRefs": [{ "contractField": "continue", "index": 1 }],
      "operands": [
        { "slot": "<id>", "required": true, "description": "the conversation id of the review to resume" },
        { "slot": "[--decided @f]", "required": false, "description": "decisions already made; the reviewer must not re-raise them (anti-circling)" },
        { "slot": "[--focus \"…\"]", "required": false, "description": "what this round must look at (repeatable)" },
        { "slot": "[--nonce <n>]", "required": false, "description": "the flow dispatch nonce — the plain-argument lane onto the AW_REVIEW_NONCE seam (a continuation manifest carries fingerprint null)" }
      ],
      "guardrails": [
        { "value": "a continuation receipt is fresh:false — informational only, never a gate pass", "enforcement": "enforced", "source": "capability.json roles.review.contract.receipt" }
      ],
      "customHooks": ["AGY_PROBE"]
    },
    {
      "key": "run",
      "kind": "primary",
      "role": "probe",
      "purpose": "Send a raw advisory prompt to a selectable model and print the reply.",
      "whenToUse": [
        "a one-off question that needs no repo grounding",
        "reaching a specific model (Gemini, Claude, GPT-OSS) from the terminal",
        "a throwaway probe of the CLI, a model, or the wrapper plumbing"
      ],
      "whenNotTo": ["a code or plan review — agy-review owns the grounded posture and the receipt"],
      "descriptor": "agy-run <prompt|-|@file> -- <extra agy flags...>",
      "operands": [
        { "slot": "<prompt|-|@file>", "required": true, "description": "the prompt text, - to read it from stdin, or @path to read it from a file" },
        { "slot": "<extra agy flags...>", "required": false, "description": "raw agy flags passed straight through after --" }
      ],
      "guardrails": [
        { "value": "subscription-only — every *_API_KEY env var is unset before the run", "enforcement": "enforced", "source": "bin/agy.sh" },
        { "value": "any model is selectable via AGY_MODEL; the default is Gemini 3.7 Flash (High)", "enforcement": "advisory", "source": "bin/agy.sh" },
        { "value": "hard wall-clock cap AGY_HARD_TIMEOUT (built-in default 5m)", "enforcement": "enforced", "condition": "only while timeout(1)/gtimeout is on PATH — otherwise the wrapper warns and runs uncapped", "source": "capability.json settings.AGY_HARD_TIMEOUT" },
        { "value": "the prompt rides a single argv — over AGY_MAX_PROMPT_BYTES (120000) the run refuses", "enforcement": "enforced", "source": "bin/agy.sh" },
        { "value": "no review posture, no grounding, no receipt — the reply is raw model output", "enforcement": "advisory", "source": "bin/agy.sh" }
      ],
      "customHooks": ["run"]
    },
    {
      "key": "AGY_PROBE",
      "kind": "env-hook",
      "parents": ["review.code", "review.plan", "review.diff", "review.continue", "review.conversation"],
      "purpose": "Silence the off-frontier model advisory for a THROWAWAY probe review.",
      "whenToUse": [
        "a probe whose answer cannot depend on the model",
        "deliberately reviewing with a cheaper non-frontier model"
      ],
      "whenNotTo": ["any run whose output informs what ships — a probe never attests"],
      "descriptor": "AGY_PROBE=1 agy-review code [--facts @<facts-file>]",
      "operands": [
        { "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)" }
      ],
      "guardrails": [
        { "value": "a probe review mints a probe-marked receipt the review-state gate rejects", "enforcement": "enforced", "source": "agent-workflow-kit tools/review-state.mjs" }
      ]
    }
  ],
  "settings": [
    {
      "key": "AGY_HARD_TIMEOUT",
      "kind": "duration",
      "default": null,
      "appliesTo": ["agy-run", "agy-review"],
      "effect": "hard wall-clock cap via timeout(1), duration string (e.g. 5m, 30m, 90s); built-in default: agy-run = AGY_TIMEOUT (5m), agy-review 30m."
    },
    {
      "key": "AGY_REVIEW_ALLOW_ADDDIR",
      "kind": "boolean",
      "default": "0",
      "appliesTo": ["agy-review"],
      "retired": "the --add-dir offload is retired: headless agy AUTO-DENIES its own read_file tool, so an offloaded change set could return a confident fabrication with no way to tell. An oversized code review is now DELIVERED as a chunked feed with a per-part delivery proof. The key stays recognized so an existing settings line never warns as unknown, but it arms nothing; clear it with --unset.",
      "effect": "RETIRED — recognized so an existing settings line never warns as unknown, but it arms NOTHING. A set value prints the retirement notice naming the chunked-feed lane that replaced it."
    },
    {
      "key": "AGY_REVIEW_MAX_TOTAL_BYTES",
      "kind": "integer",
      "min": 1,
      "max": 100000000,
      "default": "240000",
      "appliesTo": ["agy-review"],
      "effect": "agy-review code: the ceiling on the SUM of all outgoing prompt bytes the chunked feed may send (every feed-turn framing block, every body, the final turn). Checked BEFORE the first turn is spent; past it the fed review refuses. An economy guard, not the correctness guard — correctness is the per-part delivery echo."
    }
  ],
  "networkHosts": ["*.googleapis.com", "accounts.google.com", "antigravity-unleash.goog", "lh3.googleusercontent.com"],
  "writableDirs": [{ "env": null, "default": "~/.gemini/antigravity-cli" }],
  "detect": {
    "installed": {
      "env": "ANTIGRAVITY_CLI_BRIDGE_DIR",
      "default": "~/.claude/skills/antigravity-cli-bridge",
      "file": "SKILL.md"
    }
  },
  "cost": "subscription",
  "quota": { "kind": "subscription", "finite": true },
  "provenance": { "author": "sabaiway", "source": "github:sabaiway/agent-workflow" }
}
