Skip to content

Fix #71: complete the .agent issue-layer mirror; add a parity guard - #118

Open
laird wants to merge 26 commits into
masterfrom
fix/agent-mirror-parity
Open

Fix #71: complete the .agent issue-layer mirror; add a parity guard#118
laird wants to merge 26 commits into
masterfrom
fix/agent-mirror-parity

Conversation

@laird

@laird laird commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Ports the still-relevant part of the stale #74 onto current master. #74 itself
branched before the Jira/ADO backends, verify-shipped.sh, claimed-issue-numbers.sh,
the hardenimprove rename and model-config.md landed, so merging it would
delete ~4,352 lines of current master. This PR takes only the part that is still
a live defect.

The defect

CLAUDE.md declares plugins/.agent/ parity CRITICAL, but nothing enforced
it and the issue layer had drifted badly on master:

file state before
issues-gh.sh absent from .agent/ — no GitHub backend on the Antigravity side
issue-source-lib.sh absent from .agent/ — no issue-source resolution
issue-fns.sh pre-dispatcher version; defined 6 of the 9 contract verbs
issues-jira.sh 145 lines behind; still on the removed v2 search endpoint
issues-file.py 438 lines behind
issue-config.sh 4 lines behind

The missing verbs are the user-visible failure: .agent/workflows/fix.md calls
issue_claim, issue_release and issue_any_claimable, so the Antigravity
/fix exited 127 at its preflight check on every run. The stale
issues-jira.sh still used POST /rest/api/2/search, which Atlassian removed
from Jira Cloud (HTTP 410, CHANGE-2046) and which #100 fixed on the plugins side
only.

The fix

These seven files are shared infrastructure with no platform-specific content —
the .agent/ copies were simply older. They are now byte-identical to
plugins/autocoder/scripts/ (verified by matching git blob hashes and file
modes): issue-fns.sh, issue-config.sh, issues-file.py, issues-gh.sh,
issues-jira.sh, issues-ado.sh, issue-source-lib.sh.

The guard

tests/test_agent_mirror_parity.sh is what stops this recurring. It asserts:

  1. every shared file is present in the mirror;
  2. each is byte-identical across mirrors;
  3. all 9 contract verbs resolve on both sides;
  4. --state blocked returns JSON rather than being forwarded to gh issue list,
    which rejects it.

Libraries are sourced inside a throwaway repo with a poisoned gh on PATH, so
a resolution regression cannot reach the real tracker; a tripwire assertion fails
the run if anything shells out to the real gh.

Against master it fails 10 of 19 assertions. On this branch it passes 19/19.

Known remaining gap

.agent/scripts/start-parallel-agents.sh still has no issue-source wiring at all
(zero references to resolve_effective_issue_source, ISSUE_SOURCE or
ISSUE_DIR_PATH, vs. 9 on the plugins side). That is issue #88 and a separate,
larger port — the two scripts differ structurally by ~233 lines. This PR
deliberately leaves it, but now makes issue-source-lib.sh available in the
mirror to wire against.

Verification

  • tests/test_agent_mirror_parity.sh — 19/19 pass (10 failures on master)
  • all 18 tests/test_*.sh suites pass
  • bash -n over plugins/autocoder/scripts/*.sh and .agent/scripts/*.sh
  • py_compile on both issues-file.py copies

Python tests were not run — pytest is not installed in this environment.

Closes #71. Supersedes #74, which should be closed as stale.

🤖 Generated with Claude Code

laird and others added 26 commits August 7, 2026 15:36
…g to N-clean; scope + exercise preflight; swarm cadence)
Design spec for adding a human-gated planning capability to the manager
session (brainstorm → spec → critical review → decompose to stories →
existing fleet implements), plus renaming /fix→/dev and /fix-loop→/dev-loop
with aliases. Reuses existing skills and the decomposed/subtask convention;
adds two backlog-aware behaviors to the manager loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Critical-design-review round 1 approved the planning-pipeline spec as-is:
0 literal-wrongness findings, 0 forced decisions. Empirically confirmed the
two load-bearing hand-off facts (subtask is claimable; decomposed parents are
excluded from claiming). Recorded the CDR approval in the spec status and
carried the three CIR-deferred items forward as notes B8/B9 (+ existing B5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…eview-1 to autocoder-planning-pipeline-implementation-plan
Tracks the 2026-07-28 handoff documenting the /fix→/dev rename and
peters-toolkit:bugfix integration, plus the still-unaddressed critical
review of the planning-pipeline implementation plan.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… reimplemented on master + platform drift repair
… exclusion, drift repair), marketplace to 3.32.0
…ound/improved/learned per round, verdict chapter)
…e v2 removal

Atlassian removed POST /rest/api/2/search from Jira Cloud (HTTP 410,
CHANGE-2046). list and any-claimable now use POST /rest/api/3/search/jql
with an explicit fields list, nextPageToken pagination (no startAt), and
existence-of-first-page instead of the removed total for any-claimable.
Issue lifecycle endpoints stay on v2 (not removed; plain-string bodies).
The fake serves the new contract, enforces a settable page cap to exercise
the token loop, and returns 410 on v2 search so regressions cannot pass.

Live verification against real Jira Cloud pending by coordinator.
…text

Live smoke showed /rest/api/3/search/jql returns description as an ADF
document object, not v2's plain string. The list reshape now walks ADF
content nodes collecting text (paragraphs joined with newlines; tolerates
null, plain strings, malformed nodes), so body stays a plain string for
all consumers. v2 CRUD read paths are untouched (still plain strings).
The fake now serves ADF descriptions from v3 search to pin the contract.
…-smoke-test.sh; live validation pending an ADO sandbox)
…gents

The SKILL.md had no model guidance. Top-level coordinator (scope/grade/fix
decisions) uses the deep model; subagents and swarm workers use the balanced
model. Mirrors the autocoder manager/worker tier pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… model selection (#110)

* feat(autocoder): add model-config startup confirmation and env-var-driven model selection

Autocoder agents now resolve model tiers from env vars → .autocoder.json →
built-in defaults (claude-opus-5 / claude-sonnet-5 / claude-haiku-4-5 on
Claude Code; gemini-2.5-pro / gemini-2.0-flash on Antigravity).

On first run with no model config found, the agent presents the defaults and
asks the user to confirm or override before proceeding.  The confirmed models
are exported as MANAGER_MODEL / WORKER_MODEL / FAST_MODEL and referenced in
every Task tool call in the workflow so agents actually use them.

Also adds skills/autocoder/references/model-config.md documenting the tier
system and how to persist overrides via .autocoder.json.

Parallel maintenance: plugins/autocoder/commands/fix.md ↔ .agent/workflows/fix.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: bump autocoder to 4.11.0, marketplace to 3.33.0

Reflects model-config startup confirmation and env-var-driven model
selection added in the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
#112)

Switch fix.md and model-config.md from full API model IDs (claude-opus-5)
to platform tier shorthand (opus/sonnet/haiku for Claude Code, pro/flash
for Gemini). Agents inherit credentials from the running session — no
separate API keys needed.

Rename skills/harden → skills/improve to reflect the general improvement
and validation loop, not just security hardening.

Bump autocoder 4.11.0 → 4.12.0, marketplace 3.33.0 → 3.34.0.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- test_issues_gh_search.sh (11 failures): BASH_ENV=/home/laird/.bashenv
  prepends ~/bin to PATH on every bash invocation, putting the real gh
  before the test stub. Fix: pass BASH_ENV="" when invoking the backend.

- test_issue_source_lib.sh (1 failure): bash reverts VAR=val assignments
  on shell-function calls after the function returns, so the previously-
  exported ISSUE_DIR_PATH from the CLI-dir test step was restored instead
  of the function's new value. Fix: export explicitly before the call.

- test_worker_launch_lib.sh (1 failure): Gemini workers should use the
  /fix-loop interactive command (matching .agent/workflows/fix-loop.md),
  not a non-existent gemini-fix-loop.sh shell script. Fix: align
  worker-launch-lib.sh with the test expectation.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
#96)

restart-worker.sh killed the hung worker but never relaunched it, leaving the
pane at a bare shell while still printing "✅ Worker restarted".

Root cause: callers derive AGENTS_REPO_ROOT as SCRIPT_DIR/../../.., which is
only correct for a repo checkout. An installed plugin lives at
cache/plugin-marketplace/autocoder/<version>/scripts, so that walk lands on the
cache root; appending plugins/autocoder/scripts/claude-worker-loop.sh yields the
hybrid path from the report — real in neither the cache nor marketplace layout.

Changes:
- worker-launch-lib.sh: resolve the loop script from the lib's own directory
  (WORKER_LAUNCH_LIB_DIR); both ship in the same scripts/ dir. Fail loudly with
  a non-zero return if it is missing instead of emitting an unusable path.
- restart-worker.sh: after sending WORKER_CMD, capture the pane and exit
  non-zero if it reports "No such file or directory"/"command not found", so a
  killed-but-not-restarted worker can no longer be reported as success.
- test_worker_launch_lib.sh: assert the emitted loop path EXISTS on disk when
  repo_root does not follow the checkout layout, and that it is not derived from
  repo_root. Verified red before the fix with exactly the reported path shape.

Verification: 17/17 shell unit tests pass; bash -n + py_compile clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
CLAUDE.md declares plugins/ <-> .agent/ parity CRITICAL, but nothing
enforced it and the issue layer had drifted badly:

  - .agent/scripts/ was missing issues-gh.sh and issue-source-lib.sh
    entirely — the Antigravity side had no GitHub backend and no
    issue-source resolution.
  - .agent/scripts/issue-fns.sh was the pre-dispatcher version: it
    inlined the GitHub backend and defined only 6 of the 9 contract
    verbs. .agent/workflows/fix.md calls issue_claim, issue_release and
    issue_any_claimable, so the Antigravity /fix exited 127 at its
    preflight check on every run.
  - issues-jira.sh still used POST /rest/api/2/search, removed from Jira
    Cloud (HTTP 410, CHANGE-2046) and fixed on the plugins side by #100.
  - issues-file.py and issue-config.sh trailed by 438 and 4 lines.

These files are shared infrastructure with no platform-specific content,
so the mirror is now byte-identical to plugins/autocoder/scripts/ (same
blob hashes, same modes) for all seven: issue-fns.sh, issue-config.sh,
issues-file.py, issues-gh.sh, issues-jira.sh, issues-ado.sh and
issue-source-lib.sh.

tests/test_agent_mirror_parity.sh is the guard that stops this
recurring. It asserts presence, byte-identity, that all 9 contract verbs
resolve on BOTH sides, and that `--state blocked` returns JSON rather
than being forwarded to `gh issue list` (which rejects it). It sources
each lib inside a throwaway repo with a poisoned gh on PATH, so a
resolution regression cannot reach the real tracker. Against master it
failed 10 of 19 assertions; it now passes 19/19.

Known remaining gap, left for #88: .agent/scripts/start-parallel-agents.sh
still has no issue-source wiring at all. It now has issue-source-lib.sh
available to wire against.

Verified: all 18 tests/test_*.sh suites pass; bash -n over both script
dirs; py_compile on both issues-file.py copies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.agent mirror issue layer is stale: workflows call issue_claim/issue_release/issue_any_claimable which do not exist

1 participant