gh:#1924 PR4 — Porting Agy to the HarnessAdapter Protocol
The Broader Goal at the End of the Previous PR
LIVE-22 (#1964) had just closed the GitHub-identity zone-boundary gap, clearing the way back to the adapter migration. The goalpost coming into this PR: PR4 of the plan, porting Agy next, following the exact same discipline PR2 (Codex) and PR3 (Grok) had already established — one harness at a time, verified against that harness's own real failure modes before moving on.
Strategic Shifts in This PR
None — PR4 exactly as scoped in the plan.
What This PR Shipped
AgyAdapter implements the HarnessAdapter protocol for Agy (Gemini):
translate_permissions(): no permission grant →[]; a read-only grant →["--mode", "plan"]; any write grant →["--sandbox"].build_cmd(): delegates to_dispatch_flags_for_agent("agy")plus the translated permission flags, matching the patternCodexAdapter/GrokAdapteralready established.classify_failure()/parse_output(): classifies the 429RESOURCE_EXHAUSTEDcredit-exhaustion failure mode this session has hit live against Agy more than once (see the standingGrok auth / Agy fallbackmemory — Agy's known failure signature).
Caught in Review
The first review found a real gap: parse_output() returned only raw_text and failure,
missing the lifecycle_events and compatibility_evidence population that CodexAdapter and
GrokAdapter both do by importing compatibility_evidence, parse_output from
synlynk.lifecycle inside the method body. Without it, Agy dispatches would silently lose
lifecycle telemetry that the other two ported harnesses already report correctly — exactly the
kind of asymmetry the adapter pattern is supposed to prevent by construction, caught here
because it wasn't. The fix was scoped tightly to synlynk/harness_adapters/agy.py and its test
file, mirrored the Codex/Grok pattern exactly, added a regression test asserting both fields
populate, and came back with a fresh APPROVE on re-review.
This PR also hit the same README test-count CI gate as #1964, a second time, for the same
underlying reason — this PR's own new tests pushed the branch's true pytest --collect-only
count past what #1964 had already synced it to (3722 → 3727). Fixed the same way: a direct
commit on the PR's own branch, not a separate docs PR, since the gate is branch-scoped.
What Was Achieved Toward the Long-Arc Goal
Three of four harnesses (Codex, Grok, Agy) are now off LegacyAdapter. Each port so far has
independently caught something real — Grok's port surfaced a stale capability-routing bug that
needed its own fix PR; Agy's port caught a lifecycle-telemetry gap in review before it shipped.
The strangler pattern is doing exactly the job it was designed for: making each harness's quirks
a visible, testable, single-adapter concern instead of a silent gap in a shared conditional.
The New Goalpost
PR5 is the last port: Claude and local, then delete LegacyAdapter once nothing in the
registry still depends on it — closing out gh:#1924 entirely.
Refs #1924.