codex-agy-worker
A Codex Agent Skill for bounded Antigravity CLI delegation with independent Git-scope checks and driver-owned verification.
Use Codex CLI to delegate repository exploration, features, and project-scale
coding to Antigravity CLI (agy). Codex—not the worker report—reviews the diff,
runs build/test/lint checks, and decides whether the result is verified, partial, or
blocked.
Quick start
Requires a POSIX-compatible environment with Bash, Python 3, git, Codex CLI, and
agy on PATH. Native Windows is untested; WSL may work on a best-effort basis.
Install the Agent Skill from its Git-backed Codex marketplace:
codex plugin marketplace add cagdasyurekli/codex-agy-worker
codex plugin add codex-agy-worker@codex-agy-worker
Start a new Codex session after installation. The marketplace packages the same
canonical skills/agy-worker/ bundle; it does not duplicate or download a second
runtime when the skill runs.
Or review and install directly from GitHub:
git clone https://github.com/cagdasyurekli/codex-agy-worker.git
cd codex-agy-worker
./install.sh
Review the selected source commit before either installation path. The marketplace flow was tested from an immutable Git commit with isolated Codex state, including add, discovery, install, removal, and exact installed-skill byte parity. Installation does not authorize a provider dispatch or repository transmission.
Try the evidence boundary offline
./proof-demo.sh
The demo uses two private synthetic Git repositories, invokes no provider or network, and changes neither this checkout nor your credentials. It demonstrates two fixed gate cases only; it is not a security certification or proof of general correctness.
First real task
Before an agy-backed request, approve the exact repository/path content that may be
sent through agy to Google/Gemini. Keep credentials and denied paths out of scope;
read PRIVACY.md before use.
After installation, start a new Codex session and ask:
Use the agy-worker skill to add error-path tests for the parser modules under
/absolute/path/to/project/src/. Allow changes only undertests/, verify withpython3 -m pytest -q tests/test_parser.py, and preserve accepted work on a branch.
Codex creates an isolated worktree, asks for provider-transmission approval when it has not already been granted for that exact scope, inspects the resulting diff, and runs driver-owned checks. A worker can discover ordinary project structure; it is not limited to mechanical edits or a predeclared file list.
Learn how to verify an agent candidate without trusting its report.
The evidence pipeline
Bash + Python 3 + git. No Node and no MCP daemon. A deliberately started job may have one private, per-job local controller; it is not a shared service.
# Codex dispatches a bounded job to agy...
BASE="$(git -C "$WT" rev-parse HEAD)" # capture before dispatch
echo "$TASK" | AGY_WORKER_MODE=accept-edits ./agy-worker.sh \
--workdir "$WT" --add-dir "$WT" > envelope.json
# ...then independently verifies it, rather than believing the report.
./qa-gate.sh --envelope envelope.json --repo "$WT" --base "$BASE" \
--only 'tests/**' --expect-edits \
--verify "cd $WT && pytest -q"
Why another one of these?
There are already several Codex→agy delegators — codex-agy-delegator, codex-antigravity-bridge, agy-mcp, antigravity-cli-mcp, and antigravity-for-claude-code. Most are MCP servers; several are more featureful than this one. This project keeps one agy backend and does not claim validated native-Windows support.
Its differentiator is that Codex does not confuse a worker report with evidence. The worker's JSON report is a claim. The gate independently derives bounded facts from the repository, while Codex uses those facts and driver-owned checks to decide whether the result is verified or needs more work:
| The worker... | Gate | Exit |
|---|---|---|
| edits files it never declared | diffs the repo, compares to files_changed |
10 |
| declares files it never touched | same check, other direction | 10 |
| reports commands or tests on a completed candidate | treats them as untrusted data and executes none | 11 |
| returns a malformed envelope | validates the complete checked-in schema | 12 |
claims completion, changed nothing under --expect-edits |
diff is empty | 13 |
| makes a plausible but wrong fix | runs the driver's own --verify command |
14 |
| asks for a human or reports partial/failed/blocked | checks scope, then routes without accepting | 15 |
changes files outside a driver-owned --only policy |
rejects even if the worker declared them | 10 |
--verify is mandatory for acceptance. The gate never executes worker-supplied shell
text, and it hashes the Git diff plus every nontracked path—including ignored files—
before and after verification so a passing verifier cannot silently rewrite the
candidate.
The forty offline suites need no agy provider call, network access, API key, or GitHub login.
GitHub Actions cost and quota fallback
For a public repository, standard GitHub-hosted Actions runners do not consume the owner's included minutes. A private fork or a future visibility change is different: macOS runners cost substantially more than Linux runners, so the workflow deliberately avoids a second full run after a normal merge.
The required test aggregate job verifies four fail-closed CI shards (dispatcher,
dispatcher-remediation, other-a, other-b) on pull requests and exact-SHA manual dispatch.
Each shard checks out the exact immutable commit (github.event.pull_request.head.sha or
validated head_sha), enforces committed-range diff hygiene, and runs its registered stage subset.
Every shard emits a mode-0600 receipt binding exact HEAD SHA, canonical inventory digest,
expected/observed stage IDs, and outcome without recording paths, commands, environment, logs, or credentials.
GitHub retains the uploaded privacy-safe receipt artifact for one day; it is repository workflow evidence,
not an owner-private local file after upload.
The required aggregate test job with if: always() downloads all receipts within the run and succeeds
only if all four unique shard receipts exist, all producers succeeded, all match expected head/inventory,
and every canonical stage ran exactly once. Lower CI wall time from parallelization does not mean
lower total compute, provider usage, token usage, cost, or weaker verification. Normal squash merges
preserve the tested tree; the post-merge commit has a new identity but does not need a duplicate full-suite run.
The job is also available by explicit manual dispatch for an exact release comparison: supply committed base_sha and head_sha.
If a private fork's quota is unavailable, run the same fail-fast offline suite locally:
./scripts/ci-offline.sh
It runs the static checks and all forty offline suites without requiring a
network or provider call and without intentionally inspecting account-HOME contents.
Ambient local tools may still consult their ordinary user configuration. Keep the
command's exact summaries together with the commit,
tree, and git diff --check evidence. On a clean tracked/untracked worktree, an
optional --timing-report <PATH> argument records ordered per-stage observational
monotonic wall time in a mode-0600, no-overwrite JSON report bound to the exact HEAD
SHA and canonical inventory digest;
it contains no paths, commands, environment values, logs, credentials, provider data,
timestamps, or host identity, and does not claim reduced compute, lower provider
usage, or weaker acceptance. This is local evidence only: it never satisfies
the protected GitHub test check. After availability returns, manually dispatch the
exact comparison before publishing or releasing unless the repository owner explicitly
changes the protection policy. The daily compatibility watch remains macOS-specific;
the weekly metadata-only feedback watch uses Linux because it has no macOS contract.
See GitHub's Actions billing guidance
and workflow concurrency documentation.
See the evidence boundary in under a minute
./proof-demo.sh
This repository-only starter proof creates two independent private temporary Git
repositories, exercises the maintained gate once on an exact synthetic edit and once
on a plausible but incomplete synthetic envelope, then removes both repositories. It
does not invoke agy, access the network, inspect credentials, or change the current
checkout. The three-line result proves only that these two fixed cases produced the
expected gate exits. gate-passed is not a human review, accepted candidate, general
correctness claim, security certification, benchmark, or production validation.
Integrations and forks can run the full public gate contract against their own entry point:
./conformance/run.sh --gate /path/to/their/qa-gate.sh
The versioned eleven-fixture kit requires exact exits for acceptance, scope, ignored-file, untrusted-claim, malformed-envelope, no-op, verifier-failure, verifier-mutation, human-required, mutable-base, and missing-verifier cases. Passing means fixture compatibility only—not security certification, real-job quality, Receipt v1 support, or human acceptance. The supplied gate executes with the current user's privileges; review it first. Its execution TCB includes the supplied gate and loaded code, the local owner and same-UID processes, and OS administrators. Cleanup holds no-follow directory descriptors and deletes contents relative to them while the original parent/root identities remain exact; final pathname removal trusts that TCB. Identity drift fails closed with a possible residual, and the runner never scans for or chases a moved directory. This is not same-user tamper resistance. See the bounded claim and fixture contract.
Roadmap
The product roadmap records dependency-ordered feature slices and
their explicit implemented or deferred status. The published v0.6.0 release scope
added the reviewed Gemini 3.7 Flash low/medium/high mappings and hardened the capture
child mode and dispatch-state snapshot boundaries. The published v0.7.0 scope adds
usability-first explore/task/project workflows and same-conversation repair. The
published v0.8.0 scope adds explicit notifier
maintenance/rebind handling, bounded annotated-tag resolution, version-drift
observations, and the exact agy 1.1.13 quota-terminal classification. The published
v0.9.0 scope activates the exact agy 1.1.16 version/source/distribution and
unchanged 14-slug inventory binding, and accepts Codex 0.148.0 as an observational
baseline. The published v0.10.0 scope includes the lifecycle, recovery,
verification, and Codex-owned assurance scope, including the legacy notifier 18→21 file
refresh migration, bounded lifecycle recovery, and driver-owned verification. Immutable
historical v0.10.0 tag bytes cannot be rewritten; this source and package alignment
establishes repository truth without retroactively altering that published tag. The published v0.5.0
scope added sanitized bug/improvement drafts with exact double confirmation,
private-only security drafts, and the bounded metadata-only feedback aggregate and
weekly/manual watcher. The prior v0.4.0 scope includes daily compatibility observation,
private 30/60/90 measurement, the optional local notifier, version-drift-safe
default/literal routing, bounded updater, gate-envelope, lifecycle-Git-output,
Actions-checkout hardening, and the progress-aware per-job dispatch lifecycle. A
source checkout alone is not proof of publication; verify the exact reviewed tag and
release state separately.
The approved v0.11.0 observation-only release scope records agy 1.1.22 as a
non-activating observation,
Codex 0.150.1 as observation-only, and pins actions/checkout v6.0.2 by commit. The
required single no-retry 1.1.22 account inventory call failed without classifiable
inventory evidence. The owner explicitly approved publication of this reduced scope;
that decision does not activate 1.1.22, so the active agy baseline remains 1.1.16. Its
bounded dogfood record includes accepted Flash-high task/explore and Pro-high task
candidates plus a rejected Pro-high project candidate; Codex-owned review, tests, and
exact-head CI remain the acceptance authority. This describes release scope, not proof
that a v0.11.0 tag or GitHub Release exists.
P2-B and P2-C remain deferred because their required live terminal-event and
recurring-accumulation evidence does not exist.
Source, tests, and this README remain
the authority for current CLI behavior; every new slice still requires its own
approval, tests, review, and pull request.
Installation details and compatibility
for suite in tests/test-*.sh; do "$suite"; done
The quick-start ./install.sh command installs the Codex skill only and touches
nothing else. The loop above is an optional shell-suite smoke check.
It is not the complete offline gate. Run the full shell and Python command list in CONTRIBUTING.md before publication.
The GitHub repository is the source of truth. Review the commit you cloned before
installation. For a released snapshot, check out the exact reviewed
vMAJOR.MINOR.PATCH tag from the
GitHub Releases page
before running ./install.sh; do not substitute an unverified tag.
Requires agy (Antigravity CLI) on PATH, git, Python 3, and Bash. The core CLI
has no Windows-specific denylist, but its maintained entrypoints require a
POSIX-compatible Bash/Python/Git environment and some canonical evidence commands use
fixed POSIX paths. Native Windows is untested; WSL or another compatible environment
may work on a best-effort basis. The optional daily notifier is specifically a macOS
LaunchAgent.
The active reviewed model/effort matrix is bound to agy 1.1.22; its exact accepted
evidence and pair-to-compound-slug mappings are reconciled in
compat/reviews/agy-1.1.22-activation.md.
The earlier 1.1.22 observation remains the unchanged
historical failed-capture record. The complete 1.1.12
and 1.1.16 reconciliations remain historical, and the
earlier
1.1.16 interface observation records the
non-activating evidence that triggered the later capture and review. The agy-owned
default and explicit literal pass-through remain version-independent.
Codex 0.150.1 is the accepted observational Codex baseline; it does not grant agy
dispatch or model-selection authority. See
compat/reviews/codex-0.150.1.md.
Before spending provider quota, run the offline doctor against the repository you plan to delegate:
./doctor.sh --repo /absolute/path/to/target
./doctor.sh --repo /absolute/path/to/target --format json
The doctor is deterministic and read-only. It checks the bundled runtime, Bash 3.2,
Python 3, git and worktree support, target Git worktree, exact semantic
agy --version, and the checked-in agy version, reviewed-source, and review-date
records. Source-revision failures are reported only as match, mismatch, or unavailable;
the doctor never prints their bytes. It invokes no provider, network client, updater,
dispatch, authentication probe, or personal-config scan, and it repairs nothing.
| Exit | Overall | Meaning |
|---|---|---|
0 |
ready |
All offline prerequisites match the checked-in evidence. |
3 |
review-required |
Prerequisites work, but the agy version drifted or review is due. |
3 |
not-ready |
A prerequisite, semantic probe, repository, bundle, or metadata check failed. |
64 |
no report | Invocation or format is invalid. |
If the repository-root launcher cannot resolve a bounded symlink chain to the
canonical doctor.sh, it emits one sanitized diagnostic, no report, and exits 3.
The wrapper itself may be reached through that bounded chain, but the package-owned
skills/agy-worker/runtime path and the runtime's scripts, agents, schemas,
and compat parents must be real directories contained in the bundle, not symlinks.
The doctor also ignores caller-provided temp paths, gives every child probe one
private external workspace, and removes it before returning. HUP, INT, or TERM is
forwarded to the active probe and its descendants; interruption emits only
doctor: interrupted, no report, and exits 3.
Green covers only those offline prerequisites. It does not certify authentication,
provider availability, Codex/agy sandbox permission, task quality, or a future
dispatch. A due or drift result asks for human compatibility review; it never updates
metadata. review-required is not a blanket dispatch lock: no selector or
--tier default still delegates to agy's own default, and the explicitly approved
--literal-model surface remains an unreconciled caller-owned pass-through. Reviewed
--model/--effort resolution uses its reviewed 1.1.22 matrix evidence. Every
direct selection uses a safe executable with bounded semantic --version and strict
critical --help structure. An exact matrix-version match proceeds mechanically after
that structural probe. Compatible version drift requires Codex's explicit
--compatibility-disposition proceed --approve-help-sha SHA256 before dispatch; the
SHA must be the exact raw help digest just reviewed. The caller's exact resolved
slug is unchanged and the selection record reports
model_availability: not_assessed; it never claims that a drifted installation
offers a particular model. A structurally incompatible critical interface still
blocks reviewed direct selection. Structural acceptance, including an exact-version
match, is not semantic approval: before every reviewed direct dispatch, Codex inspects
the current bounded raw agy --help and stops if the exact caller-selected model or
effort cannot be honored. The controller never infers that decision from provider
prose. not-ready still blocks all dispatch. For a folder-only skill
copy, resolve PIPELINE as shown in
skills/agy-worker/SKILL.md and run "$PIPELINE/doctor.sh"—no checkout or fetch is
needed.
To approve compatible version drift without disclosing an executable pathname,
inspect the bounded local agy --help bytes, then calculate their raw SHA-256 with
LC_ALL=C agy --help 2>&1 | /usr/bin/python3 -c 'import hashlib, sys; print(hashlib.sha256(sys.stdin.buffer.read()).hexdigest())' and compare its digest to the sanitized
raw_help_sha256 review output. Retry the same caller-selected --model/--effort
request with --compatibility-disposition proceed --approve-help-sha set to that
matching digest. A mismatch, changed help, or unavailable probe needs a fresh review;
do not reuse an older digest.
skills/agy-worker/ is the one canonical, open-standard Agent Skill and contains its
own Bash/Python/git runtime. A folder-only copy therefore works without the rest of
the checkout and never downloads code when invoked. The repository-root commands are
compatibility wrappers for clone users. install.sh copies the same bundle and writes
a local pointer so checkout-only maintenance commands remain available; it does not
rewrite the public SKILL.md.
The repository retains .codex-plugin/plugin.json and the root-source
.agents/plugins/marketplace.json contract for the same Codex skills-only package.
The marketplace and GitHub clone paths resolve the one canonical skill bundle; see
the marketplace contract and verification boundary.
The portable Agent Skill can also be copied through the third-party skills CLI:
DO_NOT_TRACK=1 npx skills add cagdasyurekli/codex-agy-worker \
--skill agy-worker --copy
npx is only an optional installer here; the installed skill has no Node runtime
dependency. Review the copied files before use.
The public landing page source lives at docs/index.md. GitHub Pages configuration,
repository About fields, topics, and search-engine verification are separate
repository-owner actions; checked-in files do not change those settings.
Codex sandbox settings — required
agy starts a local language server and writes state under ~/.gemini. Under Codex's
default workspace-write sandbox it fails with exit 5 and empty stderr. Add to
~/.codex/config.toml:
[sandbox_workspace_write]
network_access = true
and run Codex with --add-dir ~/.gemini. Both are needed — the writable dir alone
still fails, because the blocker is the socket bind, not the file write.
With the config saved, launch an interactive session with:
codex --add-dir "$HOME/.gemini"
For a one-off codex exec invocation, pass both settings explicitly:
codex exec --sandbox workspace-write --add-dir "$HOME/.gemini" \
-c 'sandbox_workspace_write.network_access=true' "<your task>"
Use it from Codex
After ./install.sh, start a new Codex session and ask in normal language:
Use the agy-worker skill to add error-path tests for the parser modules under
/absolute/path/to/project/src/. Allow changes only undertests/, verify withpython3 -m pytest -q tests/test_parser.py, and preserve accepted work on a branch.
For a larger request, the prompt can be equally direct:
Use agy-worker to build this application in
/absolute/path/to/project/. Discover the existing structure and test commands, implement the requested behavior across the project, run the relevant checks, and repair failures in the same conversation.
Codex creates an isolated worktree, selects a workflow, dispatches agy, inspects the diff, runs driver-owned checks, and reports what is actually verified. You do not need to supply a final file list, a persona, or every test command before starting.
| What you want | Workflow | Minimum input | What Codex delivers |
|---|---|---|---|
| Understand, plan, or review a repository | explore |
Repository and question | A useful read-only report with stated coverage limits; not an exhaustive audit claim. |
| Implement a feature, refactor, or tests | task |
Repository and desired behavior | A worktree diff plus Codex-run relevant checks; failed checks can trigger a bounded repair. |
| Build an app, complete a project, or broadly audit-and-fix | project |
Repository and outcome | Repo-wide worktree changes, build/test/lint measurement, up to five total provider attempts (the initial attempt plus at most four same-conversation repairs), and an assurance label. |
| Follow a long job | async lifecycle | Job ID | Local status/bounded wait, controlled extension, or cancel state; not remote-provider truth. |
Assurance labels are intentionally practical: Codex uses verified only after its
strict review policy is met, partially_verified for useful work with unresolved
evidence, rejected for work it declines, and blocked for a genuine authority,
repository-boundary, or execution block. After it validates the exact current
candidate and Verification v2 binding, the controller persists Codex's declared
label; it does not reinterpret check counts into a different disposition. A failed
first check is a repair signal, not an automatic rejection or deletion.
Before the first dispatch for a repository, the skill identifies the paths in scope and requires explicit approval for sending that task and any worker-read repository content through agy to Google/Gemini, unless the user already approved that exact transmission. Read PRIVACY.md before use; support and project terms are in SUPPORT.md and TERMS.md.
Before every provider-launch attempt (initial run/start, resume, continue, and
restart), the packaged skill requires Codex to tell the user in one or two concise
user-facing sentences what task is being sent to AGY, the caller-selected model,
caller-selected effort (when separately selectable), and the exact resolved model slug.
For default selection where no model is selected or the default tier is used, state
truthfully that the provider default model is used and that model or effort is unresolved,
without inventing a resolved slug or thinking level. For fixed, compound, or literal models
where effort is not separately selectable, that is stated accurately without inferring
hidden backend reasoning or inventing a thinking level. The notice must precede every dispatch
attempt and remain accurate afterward. If preflight fails before provider launch, Codex
explicitly states that the task was not sent to AGY; if provider reach is genuinely uncertain,
it states that reach is unverified rather than claiming success. Direct model and effort
selection remain caller-owned, and routing recommendations are advisory.
Manual end-to-end example
Keep the pipeline checkout and target repository explicit. The job branch matters:
it prevents accepted but uncommitted work from being destroyed during cleanup.
bulk-test-writer is still experimental: it has been exercised on a real task, but
has not yet produced an accepted real delivery.
PIPELINE=/absolute/path/to/codex-agy-worker
TARGET=/absolute/path/to/your-project
WT=/tmp/agy-job-12345
JOB_BRANCH=agy/tests-parser-errors-12345
ENVELOPE=/tmp/agy-job-12345-envelope.json
JOB_ID=parser-tests-12345
BASE="$(git -C "$TARGET" rev-parse HEAD)"
git -C "$TARGET" worktree add -b "$JOB_BRANCH" "$WT" "$BASE"
if ! echo "Add error-path tests for $WT/src/parser.py.
Edit ONLY files under $WT/tests/. Use file tools on absolute paths.
Do NOT run shell commands — they execute in a scratch directory, not this repo.
The driver runs every command. Return commands_run and tests_run as empty arrays." |
AGY_WORKER_JOB_ID="$JOB_ID" "$PIPELINE/agy-worker.sh" \
--workflow task --mode accept-edits --tier bulk --persona bulk-test-writer \
--workdir "$WT" --add-dir "$WT" > "$ENVELOPE"; then
echo "Dispatch failed; inspect the sanitized terminal state/result. Resume only a candidate-free failure; handle an ERROR candidate with Verification v2, and preserve/finalize or freshly restart a CANCELED candidate." >&2
exit 1
fi
if "$PIPELINE/qa-gate.sh" --envelope "$ENVELOPE" --repo "$WT" --base "$BASE" \
--only 'tests/**' --expect-edits \
--verify "git -C '$WT' diff --check" \
--verify "cd '$WT' && python3 -m pytest -q tests/test_parser.py"; then
echo "Candidate passed the evidence gate; review the diff before preserving it."
else
GATE_RC=$?
echo "Gate rejected or routed the candidate (exit $GATE_RC)."
exit "$GATE_RC"
fi
Exit 0 means the evidence gate accepted the current state; it does not merge it. Review and preserve the work before removing the worktree:
git -C "$WT" diff
git -C "$WT" add tests/
git -C "$WT" commit -m "test: cover parser error paths"
git -C "$TARGET" worktree remove "$WT"
# Integrate JOB_BRANCH only after your normal review/PR process.
If the gate rejects the job and you intentionally want to discard it:
git -C "$TARGET" worktree remove --force "$WT"
git -C "$TARGET" branch -D "$JOB_BRANCH"
Gate failure handling is deliberately small: exits 10–14 reject the candidate, exit
15 routes its questions to a human, and exit 64 means the driver invocation is wrong.
A dispatch error starts no further provider call automatically; do not add a shell
retry loop. A candidate-free failed state may be eligible for SHA-approved exact
resume or explicit fresh restart. A terminal ERROR with a valid candidate goes
to result, driver Verification v2, then continue or finalize. A terminal
CANCELED candidate goes to result and preservation/finalization or an explicit
fresh restart; it is never resumed or continued.
Read-only inventory example
Use plan for inventory and independently spot-check the report. Exit 0 can prove
that no files changed and that the driver command passed; it cannot prove the
worker's architecture prose is accurate.
An explore result is useful input for planning but does not prove that every semantic path was inspected. Codex should spot-check material claims before relying on them; that limitation does not make an otherwise useful broad exploration inadmissible.
if ! echo "Read repository-owned files under $WT using absolute paths. Report entry points,
test commands, and risky areas. Do not run commands. Return files_changed,
commands_run, and tests_run as empty arrays." |
"$PIPELINE/agy-worker.sh" --workflow explore \
--workdir "$WT" --add-dir "$WT" > /tmp/inventory-envelope.json; then
echo "Inventory dispatch failed; do not pass its stdout to the gate." >&2
exit 1
fi
"$PIPELINE/qa-gate.sh" --envelope /tmp/inventory-envelope.json \
--repo "$WT" --base "$BASE" \
--verify "git -C '$WT' diff --quiet '$BASE' --"
# Then open a sample of every claimed path and verify discovered commands against
# package/CI files yourself before using the inventory for planning.
Two rules that make it work
- Keep the worker off the shell. Under agy's sandbox, its shell tools run in
~/.gemini/antigravity-cli/scratch, not your repo — a worker asked to survey a repo will runlsand truthfully report an empty directory. Its file tools do reach the real target. Let the worker edit files; the driver owns every command. - Absolute paths +
--add-dir. agy has no reliable notion of "the current directory" in print mode. Name the absolute path in the task text and pass--add-dir. With only one, the worker works on the wrong thing.
Personas
--persona repo-inventory|diff-reviewer|bulk-test-writer optionally inlines a role brief from
skills/agy-worker/runtime/agents/. repo-inventory measurably changed an
under-specified job from a false
survey into an honest escalation. bulk-test-writer has now been exercised on a real
Playbook-Gemini test task: the gate caught a bad first test and rejected the retry on
diff hygiene even though its focused tests passed. That proves the gate, not reliable
first-pass quality from the persona. The first dispatch consumed about 251k input
tokens and the corrective retry about 63k, reinforcing that this is for batched work,
not cheap one-line edits. diff-reviewer remains unexercised on a real job.
Personas are injected as prompt text, not via agy's --agent flag, because
--agent silently disables --json-schema enforcement (see below).
persona-evidence.sh validates the fixed shipped-persona
registry and reproduces its documentation table. All three shipped personas remain
offline-only: their records bind exact frontmatter/mode restrictions and the public
P1-C contract bytes, but that synthetic candidate does not execute a persona.
Historical real exercises lack the public Receipt/base/verifier/tool bindings needed
to promote a registry state. Future upper states require immutable public Git blobs
in three strict phases: evidence, separate approval/review, then registry transition.
This validates protected-main sequencing and exact bytes/modes, not cryptographic
reviewer identity or signatures; portable bundles reject upper states.
| Persona | Allowed modes | Evidence status | Public evidence |
|---|---|---|---|
bulk-test-writer |
plan, accept-edits |
offline-only |
P1-C public contract; persona not executed |
diff-reviewer |
plan |
offline-only |
P1-C public contract; persona not executed |
repo-inventory |
plan |
offline-only |
P1-C public contract; persona not executed |
Statuses are evidence levels, not trust labels or acceptance authority. The registry cannot rank, route, select, execute, promote, or dynamically register a persona.
Data-only workload profiles
profile.sh lists three fixed maintained skeletons without
loading a repository or dispatching anything:
./profile.sh list
./profile.sh show bounded-test-backfill
show prints canonical JSON that may suggest one maintained mode, persona, and
repo-relative path-policy shape. It is deliberately non-executable and explicitly
requires the caller to provide approval, exact repository, exact path policy,
selected tier, and verification commands. Profiles contain no repository path,
model/tier/effort value, command, external root, authorization, routing, acceptance,
dispatch, or Git action. Only the fixed hash-bound bundle is read; target repositories,
environment variables, home directories, and caller-supplied profile paths are never
profile sources.
Common options
| Worker option | Environment equivalent | Meaning |
|---|---|---|
| `--workflow explore | task | project` |
--max-cycles 1..2 |
— | explore or task total provider-attempt budget; default 2. |
--max-cycles 1..5 |
— | project total provider-attempt budget; default 5. Legacy raw mode is exactly one attempt; --max-cycles requires an explicit workflow. |
| `--mode plan | accept-edits` | AGY_WORKER_MODE |
| `--tier cheap | bulk | hard |
--model EXACT_MODEL |
AGY_WORKER_MODEL |
reviewed exact slug, or adjustable base used with effort |
| `--effort low | medium | high` |
--literal-model EXACT_SLUG |
— | CLI-only caller-owned pass-through; no matrix claim. A bounded non-gating version observation may support exact diagnostics without changing the selected model. |
--workdir DIR |
— | agy's workspace |
--add-dir DIR |
— | repeatable file-tool root; must resolve inside --workdir |
--persona NAME |
— | Optional bounded worker-role prompt; it does not authorize work or prove quality. |
--idle-timeout DURATION |
AGY_WORKER_IDLE_TIMEOUT |
no valid progress for this long ends the attempt; default 10m |
--hard-timeout DURATION |
AGY_WORKER_HARD_TIMEOUT; AGY_WORKER_TIMEOUT (deprecated alias) |
initial per-attempt deadline; default 2h |
--max-runtime DURATION |
AGY_WORKER_MAX_RUNTIME |
caller-owned absolute cap across extensions; default 12h |
| — | AGY_WORKER_JOB_ID |
safe artifact directory name |
Worker exits: 0 ok · 2 no prompt · 3 empty output · 4 schema invalid ·
5 unclassified agy failure · 6 permission gate · 7 compatibility review required ·
8 compatibility evidence unavailable · 9 idle timeout · 16 hard deadline ·
17 provider timeout (reserved) · 18 authentication failure (reserved) ·
19 provider unavailable (reserved) ·
20 local status, binding, or verification-copy runtime unavailable · 21 resume failure · 22 cancelled ·
23 output oversized · 24 provider quota exhausted · 25 provider terminal error
with a preserved valid candidate · 26 direct-selection preflight failure · 64 invalid usage.
The reserved 17–19 exits require an exact, version-bound reviewed signature.
The active agy 1.1.22 baseline has no reviewed signature allowlist for these exits,
so an unproven
provider timeout, authentication error, or provider outage remains
agy_failed_unclassified with exit 5; the supervisor does not infer a reason from
free-form stderr.
Exit 24 is narrower than a general rate-limit classifier. It currently recognizes
only the exact, structurally valid agy 1.1.13 terminal quota shape reviewed for
Issue #59. Status exposes only a bounded, decreasing retry_after_seconds; it never
prints the error text, conversation, prompt, model, path, envelope, or raw log. The
worker does not sleep, retry, restart, or change the caller's model automatically.
Wrong-version or altered quota terminals without a report remain invalid_envelope
with exit 4 and failure_stage=missing_structured_output. The exact recognized
1.1.13 quota terminal remains provider_quota_exhausted with exit 24 when it has
no report, with failure_stage=missing_structured_output.
Only provider init, step_update, and terminal result events can update v9
last_activity to provider_initialized, progress_signal, or
terminal_received. They renew only an idle lease; they never prove success or
extend the hard deadline or the caller-owned maximum.
The supervisor forwards the maximum as agy's --print-timeout, owns the shorter
local clocks and process group, and records only sanitized elapsed/progress-age/count,
attempt origin, terminal reason, and resume availability. It never prints progress,
prompts, raw stderr, or a conversation ID.
There is no automatic fresh retry or continuation. A candidate-free failed state may
offer SHA-approved resume for the exact stored conversation or SHA-approved fresh
restart. A valid provider ERROR (exit 25) candidate is unreviewed: obtain it
with result, supply driver Verification v2, then continue or finalize. A valid
provider CANCELED/CANCELLED (exit 22) candidate is preserved for result and
finalization, or an explicit fresh restart; it is never resume- or continue-eligible.
None of those outcomes is provider success. status, wait, result, extend, and
cancel describe the local controller, not agy/provider status or proven remote
cancellation. A locally cancelled job therefore reports remote_cancel_unverified.
No comments yet
Be the first to share your take.