Commit Graph

4378 Commits

Author SHA1 Message Date
Tom Boucher
fdfff96d52 fix(#2090): restore unrelated files accidentally deleted/modified by subagent
The implementation subagent cross-contaminated the branch with changes from
PR #2121 (phase-identifier parsing consolidation):
- Deleted docs/adr/2121-phase-identifier-parsing-consolidation.md (restored)
- Deleted src/phase-id.cts (restored)
- Deleted tests/phase-id.test.cjs (restored)
- Modified src/roadmap-parser.cts (restored to origin/next)
- Modified src/state.cts (restored to origin/next)

None of these are related to the Cline EoS migration.
2026-07-09 19:40:58 -04:00
Tom Boucher
68535d3011 fix(#2090): correct beforeTool test to match parity-faithful path-key contract 2026-07-09 19:38:27 -04:00
Tom Boucher
9e7f80ea69 fix(#2090): resolve lint — drop unnecessary type assertion + unused vars 2026-07-09 19:38:27 -04:00
Tom Boucher
f76f117ff9 docs(#2090): cline host-integration migration status + changeset 2026-07-09 19:38:27 -04:00
Tom Boucher
760eb71b6b feat(#2090): migrate cline onto imperative adapter + beforeTool/createAgentModel upgrades
Fold all hardcoded runtime === 'cline' / isCline branches in bin/install.js
into descriptor-driven runtime.hostBehaviors lookups (reapplyCommand,
frontmatterDialect, skipSharedHooksInstall, localTargetIsProjectRoot,
clineRulesSurface, localCommandsViaRules). Add cline-sdk-binding adapter
(ADR-1239 Phase D): UPGRADE 1 re-implements the .clinerules/hooks/PreToolUse
guard as a real AgentPlugin.hooks.beforeTool handler (fail-open, same
semantics); UPGRADE 2 wires DefaultGateway.createAgentModel params from
model_overrides/model_profile_overrides resolution (modelMode: active).
Install output is byte-identical (golden parity asserted for cline +
claude/cursor/codex/opencode).
2026-07-09 19:38:27 -04:00
Tom Boucher
a9f9c130ef test(#2090): add cline EoS migration test scaffolding (red) 2026-07-09 19:38:27 -04:00
Tom Boucher
941d3a323b Merge pull request #2131 from open-gsd/chore/2125-migrate-state-prose
fix(#2125): migrate state.cts prose parsing to canonical parser (drives #2111)
2026-07-09 19:36:55 -04:00
Tom Boucher
f50ad1d7a6 Merge remote-tracking branch 'origin/next' into chore/2125-migrate-state-prose 2026-07-09 19:10:31 -04:00
Tom Boucher
0757cdaa9c Merge pull request #2109 from open-gsd/fix/2073-antigravity-reviewer-block
fix(#2073): harden agy reviewer block (arg overflow, 404, pre-session stall)
2026-07-09 19:07:46 -04:00
Tom Boucher
fea63c65e5 docs(changeset): backfill pr 2131 for #2111
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 18:55:58 -04:00
Tom Boucher
ae1bd14691 Merge branch 'next' into fix/2073-antigravity-reviewer-block 2026-07-09 18:55:02 -04:00
Tom Boucher
b32ecd1b87 docs(changeset): Fixed fragment for #2111 (pr:0 to backfill)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 18:13:03 -04:00
Tom Boucher
bd5fcfceeb fix(#2125): route complete-phase resolver through canonical parser (review)
Orthogonal review surfaced that resolvePhaseIdForCompletePhase (state.cts) and
cmdStateCompletePhase's idempotency check still used an unanchored
/(\d+[A-Z]?(?:\.\d+)*)/i — even more permissive than the parseProsePhaseField
regex this phase fixes. Reachable corruption: after `milestone complete v0.5`,
`state complete-phase` (no --phase) mined "0.5" from the body line
"Phase: Milestone v0.5 complete" and rewrote STATE.md as "Phase 0.5 complete".

Both sites now delegate to phase-id.cts:parsePhaseFromProse (the same anchored
parser), so a milestone-closure line yields no token and the existing
"unable to resolve" guard fires instead of corrupting. Canonical tokens
(3, 03, 3A, 3.3, "3 of 5", "1 — Setup") are preserved unchanged.

Regression (tests/state.test.cjs, complete-phase suite): `state complete-phase`
on a "Milestone v0.5 complete" STATE.md now rejects and does not mine "0.5".
Demonstrated fail-first.

Refs #2125, #2121

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 18:11:55 -04:00
Tom Boucher
e7ff7be1a4 fix(#2125): migrate state.cts prose parsing to canonical parser (drives #2111)
Phase 2 of epic #2121. state.cts:parseProsePhaseField now delegates to the
anchored phase-id.cts:parsePhaseFromProse (built in Phase 1), removing this
module's independent prose phase-id regex.

Drives #2111: `milestone complete vX.Y` no longer corrupts current_phase. The
body line "Phase: Milestone v0.5 complete" previously had "5" mined from it by
the unanchored regex; the anchored parser returns { phase: null }, so
syncStateFrontmatter's #905 guard preserves the real current_phase. This also
fixes the broader family the review surfaced — every milestone completion
(e.g. v1.0 -> "0") was silently corrupting current_phase, not just .5-versions.

Regression (tests/milestone.test.cjs, in the milestone-complete suite, #2111):
`milestone complete v0.5` on a project with current_phase: "19" now preserves
"19". Demonstrated fail-first end-to-end: reverting the migration reproduces
current_phase = "5".

Closes #2125
Refs #2121

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 17:57:47 -04:00
Tom Boucher
960c3eaa15 Merge pull request #2129 from open-gsd/chore/2124-phase-id-canonical-surface
chore(#2124): build canonical phase-id.cts surface (Phase 1 of #2121)
2026-07-09 17:42:00 -04:00
Tom Boucher
80923244b1 fix(#2124): harden parsePhaseFromProse per orthogonal review (ReDoS + coercion)
Orthogonal security review of the Phase 1 surface found two issues; both fixed
and regression-tested:

- MEDIUM ReDoS: the name-extraction regexes /\(([^)]+)\)/ and
  /—\s*([^(\n]+?).../ backtrack O(n^2) on a crafted STATE.md field value with a
  long unterminated "(" / "—" run (reviewer measured ~38s at 320k chars).
  Length-bound both quantifiers to {1,200} -> linear (320k now ~100ms). A real
  phase name is far shorter than the cap.
- LOW: parsePhaseFromProse threw on non-string truthy input, unlike its three
  sibling #2121 functions. Coerce via String(value) up front.

The identical ReDoS regexes are copied verbatim from the pre-existing
state.cts:parseProsePhaseField; per the no-defer rule that surfaced defect is
fixed inline there too (Phase 2 / #2125 later supersedes that function by
delegating to the bounded phase-id.cts parser).

Adds a behavioral bound-guard regression test (a >200-char parenthetical is not
extracted) and a non-string-coercion test.

Refs #2124, #2121

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 16:33:39 -04:00
Tom Boucher
bf25e0b435 chore(#2124): build canonical phase-id.cts surface (Phase 1 of #2121)
Add the ADR-2121-locked canonical functions to src/phase-id.cts. No consumer
behavior changes — Phases 2-4 migrate the divergent call sites against them.

- parsePhaseFromProse: anchored prose parser. A phase is returned only when the
  STATE.md "Phase:" field VALUE begins with a phase token, so
  "Milestone v0.5 complete" yields { phase: null } instead of "5" (the #2111
  root cause: the old unanchored \b(\d+..)\b mined the minor-version digit).
  Name extraction (parenthetical / em-dash tail, minus status words) unchanged.
- stripConfiguredProjectCodePrefix / isForeignPrefixedPhaseQuery: config-aware
  prefix policy. A foreign prefix (MEM-01 when the configured code is LKML) is
  preserved rather than collapsed to a bare numeric phase — the #2104 fix's
  canonical home (consumed later, outside this epic's critical path).
- roadmapPhaseLookupSources: moved from roadmap-parser.cts so phase-id.cts is
  the single owner of the exact -> numeric -> prefix-tolerant ordering.
  roadmap-parser.cts now imports it (behavior-identical); its two now-unused
  imports (phaseMarkdownRegexSourceExact, OPTIONAL_PROJECT_CODE_PREFIX_SOURCE)
  are dropped.

Tests: subject-named suites in tests/phase-id.test.cjs covering the ADR
boundary set (v0.5, v1.0, MEM-01, AB-29, bare 29, zero-padded 029) plus two
fast-check properties: the #2111 "Milestone vX.Y complete never yields a phase"
invariant and a parse/normalize property.

Extend-never-mutate: the 12 pre-existing phase-id.cts exports are unchanged.

Closes #2124
Refs #2121

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 16:13:06 -04:00
Tom Boucher
d8782f772a Merge pull request #2123 from open-gsd/docs/2121-phase-id-parsing-adr
docs(#2121): add ADR-2121 phase-identifier parsing consolidation (Phase 0)
2026-07-09 15:50:01 -04:00
Tom Boucher
12d50093e1 docs(#2121): add ADR-2121 phase-identifier parsing consolidation (Phase 0)
Phase 0 of the #2121 epic — an ADR-only PR that LOCKS the contract Phases
1-4 execute against. No production code lands here.

Locks:
- phase-id.cts as the single canonical owner of phase-identifier parsing.
- New pure exports Phase 1 adds: parsePhaseFromProse (anchored; fixes the
  #2111 "Milestone v0.5 complete -> 5" class), stripConfiguredProjectCodePrefix
  / isForeignPrefixedPhaseQuery (config-aware; the #2104 fix's home),
  and roadmapPhaseLookupSources moved in as sole owner of the 3-source
  ordering (fixes the #2114 2-vs-3-source divergence).
- Extend-never-mutate on the 12 existing exports (normalizePhaseName has a
  CRITICAL 84-symbol / 20-caller blast radius) — Hyrum's Law.
- The exact exact->numeric->prefix-tolerant lookup ordering.
- A behavioral anti-divergence contract: reference-identity guard +
  scripts/lint-phase-id-drift.cjs scanner, modeled on the repo's proven
  capability-precedence-parity / package-identity-drift patterns.

#2104 remains blocked on PR #2105 and off this epic's critical path.

Adds the docs/adr/README.md index row. Docs-only; no changeset required
(no-changelog).

Closes #2121

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 15:09:53 -04:00
Tom Boucher
d0745a0e91 Merge pull request #2120 from open-gsd/feat/2089-cursor-eos-migration
feat(#2089): migrate Cursor onto EoS imperative adapter + hook-bus/dispatch upgrades (ADR-1239)
2026-07-09 14:17:23 -04:00
Tom Boucher
39116ba001 docs(changeset): backfill pr 2120 for #2089 2026-07-09 13:59:48 -04:00
Tom Boucher
c25b212c62 revert: restore gsd-cursor-pre-tool.js dead imports (golden parity)
Reverts the LOW-severity dead-import removal (require('fs')/require('path'))
that changed the file hash and broke 9 golden-install-parity fixtures. The
golden test computes per-runtime hashes of installed hook files; regenerating
all 9 fixtures for a cosmetic cleanup is disproportionate. Dead imports are
harmless (Node caches built-in requires) — noted as a follow-up nit.
2026-07-09 13:39:24 -04:00
Tom Boucher
45f3a2a5f9 fix(#2089): wire adapter into install path + address all review findings
MEDIUM fixes (code review):
- Wire resolveManagedHookEvents + resolveHookScripts + buildHookBusEntries
  from imperative-hook-bus.cts into writeCursorHooksJson — the install path
  is now truly descriptor-driven (reads hostBehaviors.managedHookEvents),
  not a hardcoded constant that happens to match the descriptor. bin/install.js
  passes the descriptor list via opts.managedHookEvents.
- buildHookBusEntries is now consumed (was dead code); entry-building is no
  longer duplicated inline.
- Remove try/finally from cursor-hook-bus-upgrade.test.cjs test bodies
  (violated CONTRIBUTING.md L342; redundant with t.after cleanup).

LOW fixes:
- Remove dead require('fs')/require('path') from gsd-cursor-pre-tool.js
- Fix resolveManagedHookEvents docstring (all-invalid fallback behavior)
- Add src/runtime-hooks-surface.cts to the AC2 source-guard file list

Security review: no CRITICAL/HIGH/MEDIUM findings (3 LOW are pre-existing
#777 baseline patterns, not regressions).
2026-07-09 13:17:04 -04:00
Tom Boucher
fad5094587 fix(#2089): redesign scanner property test — logic/results, not wall-clock
Replaces the timing-dependent execFileSync(timeout:5000) approach with a
spawnSync-based runHook that tests the scanner's RESULT (exit code + output
shape), never how long it takes.

Root design flaw in the prior approach: execFileSync's timeout (5000ms)
was identical to the scanner's own internal setTimeout(5000ms), creating a
non-repeatable race (F.I.R.S.T. violation: not Repeatable). Under concurrent
test-chunk load — which #2089's 3 new cursor test files redistribute —
node22's event-loop scheduling let execFileSync's SIGTERM win the race,
producing err.status=null → exitCode=1 → spurious property-test failure.

Redesign (F.I.R.S.T.):
- spawnSync (not execFileSync): non-zero exits return a result object,
  not an exception — cleaner for property tests
- Non-serializable payloads (BigInt, circular refs, Symbol) are SKIPPED:
  the scanner receives JSON via stdin, so these values are outside its
  protocol — JSON.stringify throwing is a test-harness artifact, not a
  scanner defect
- 30s safety-net timeout is NOT a test assertion: scanner exits in <100ms;
  30s only catches a genuinely hung process (6x the scanner's own 5s
  internal timer → no race possible)
- Assertions check exit===0 and output structure, never timing

qa-test-architect pipeline: risk=HIGH (security boundary); automation=
subprocess (real shipped hook); test-cases cover happy/boundary/negative/
independence; verified via gsd-test.
2026-07-09 09:36:33 -04:00
Tom Boucher
a8d9dbe02a fix(#2089): widen read-injection-scanner property test timeout to avoid node22 race
The property test's execFileSync timeout (5000ms) was identical to the
scanner's own internal stdin-timeout (hooks/gsd-read-injection-scanner.js:109,
also 5000ms). Under concurrent test-chunk load on linux-node22 — which #2089's
3 new cursor test files redistribute — the scanner subprocess's stdin 'end'
event can fire late enough that execFileSync's SIGTERM arrives before the
scanner's own process.exit(0), producing err.status=null → exitCode=1 →
spurious property-test failure.

The scanner has no process.exit(N!=0) paths; the only non-zero exit is from
the signal-kill race. Doubling the test ceiling to 10000ms gives the scanner's
5000ms internal exit a 5s buffer to win the race deterministically on every
node version.
2026-07-09 09:16:37 -04:00
Tom Boucher
a53c5462e6 chore(#2089): gitignore compiled imperative-hook-bus adapter + fix Context7 typo
- Add /gsd-core/bin/lib/host-integration-adapters/imperative-hook-bus.cjs to
  .gitignore (tsc-emitted build artifact per ADR-457 convention; matches the
  sibling adapter entries at .gitignore:70-89). The subagent authored the
  .cts source but missed this entry, leaving the compiled output untracked.
- Fix cosmetic 'Context3' -> 'Context7' typo in test section header comment.
2026-07-09 02:07:08 -04:00
Tom Boucher
c68bca55cf test(#2089): regenerate all golden fixtures for managed-hooks-registry + cursor hook additions 2026-07-09 01:19:25 -04:00
Tom Boucher
24896ddac7 fix(#2089): register 4 new cursor hook scripts in build + managed-hooks whitelists 2026-07-09 00:58:09 -04:00
Tom Boucher
303a796579 docs(changeset): #2089 cursor host-integration migration + golden fixture 2026-07-09 00:21:51 -04:00
Tom Boucher
b0d985ccb3 feat(#2089): migrate cursor onto imperative adapter + hook-bus/dispatch upgrades 2026-07-09 00:21:39 -04:00
Tom Boucher
c5e5211db0 test(#2089): add cursor EoS migration test scaffolding (red) 2026-07-09 00:21:28 -04:00
Tom Boucher
96a6cf7160 Merge pull request #2110 from open-gsd/feat/2088-eos-codex-imperative-adapter
feat(#2088): [EoS/codex] migrate Codex onto the Embeddable Orchestration System — full parity + upgrades (ADR-1239)
2026-07-08 23:05:37 -04:00
Tom Boucher
8b99f4f3c3 fix(#2088): weight install-heavy test files so they spread across chunks
The targeted CI lane runs changed files UNSHARDED; #2088 touched 13 install-heavy
test files that all landed in one chunk, blowing the 600s per-chunk backstop on
the slow Windows runner (pure slowness, not a leak — per run-tests.cjs's own
comment). Weight install*/codex-* files (~10x a unit file) toward the per-chunk
budget so they spread across chunks instead of clustering; light-file chunking is
unchanged (weight 1). Adds harness regression tests (heavy split vs light control).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 22:49:25 -04:00
Tom Boucher
e8c8a5b914 docs(changeset): backfill pr 2110 for #2088 changeset
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 22:12:56 -04:00
Tom Boucher
6e773d97df feat(#2088): migrate Codex onto the Embeddable Orchestration System (ADR-1239)
Drive Codex install/uninstall through the descriptor-driven Host-Integration
Interface (declarative embedding adapter → engine surface dispatch) and fold
every positive `runtime === 'codex'` / `isCodex` projection into descriptor-driven
`runtime.hostBehaviors`. Install/uninstall output stays byte-parity-gated
(tests/fixtures/golden-install-parity/codex.json); no other runtime changes.

Three Context7-verified upgrades, each with a test on the user-reachable surface:
- Skill root → canonical $HOME/.agents/skills via a skills-kind `home` override,
  with pre-move migration cleanup (stale ~/.codex/skills/gsd-* removed on install
  and uninstall; user content preserved). Fixes getGlobalSkillsBase, writeManifest,
  and the skill-manifest inventory to honor the override so --skills-root /
  sync-skills / the manifest report the real location.
- Six new hooks.json lifecycle events (PreToolUse, PermissionRequest, PreCompact,
  PostCompact, SubagentStop, UserPromptSubmit) shared by install + uninstall;
  extendedHookEvents reconciled [] -> the schema-valid wired subset.
- Explicit `[agents] max_depth = 1` in the managed config.toml block, pinning the
  negotiated dispatch.maxDepth:1 axis. validateCodexConfigSchema now permits a
  known-scalar-only bare `[agents]` AgentsToml table (still rejects [[agents]] and
  unknown-key break-forms, #2760); mergeCodexConfig preserves the user's own
  AgentsToml scalars (max_threads etc.) instead of dropping them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 21:42:11 -04:00
Tom Boucher
88d008553d Merge remote-tracking branch 'origin/next' into fix/2073-antigravity-reviewer-block 2026-07-08 20:00:25 -04:00
Tom Boucher
dc5b89f401 test(#2073): add see #2073 ref to allow-test-rule exemption (ADR-456) 2026-07-08 18:56:27 -04:00
Tom Boucher
25ece96649 docs(changeset): backfill pr: 2109 for #2073 2026-07-08 18:38:53 -04:00
Tom Boucher
e5a1d7f5c4 Merge pull request #2108 from open-gsd/feat/2087-eos-opencode-imperative-adapter
feat(#2087): [EoS/opencode] Migrate OpenCode onto the Embeddable Orchestration System (ADR-1239)
2026-07-08 17:58:56 -04:00
Tom Boucher
dbc730d8de fix(#2073): capability-probe external killer (timeout/gtimeout) for macOS
Code review (HIGH): a hardcoded 'timeout 600 agy' fails with rc 127 on stock
macOS (no GNU timeout/gtimeout), silently losing the agy reviewer. Probe for
'timeout'/'gtimeout' via command -v and fall back to agy's native --print-timeout
alone when neither exists (mirrors scripts/base64-scan.sh). External cap (600s)
stays >= --print-timeout (540s) so it only backstops a pre-session stall. Factor
the prompt into _AGY_PROMPT to avoid duplicating the long -p string across both
branches. Update the agy + #687 tests to assert the probe + bound + fallback,
regen the 17 goldens + size baseline, refresh the maintainer-note version stamp
to 1.0.16.
2026-07-08 17:53:28 -04:00
Tom Boucher
9320f35d72 docs(changeset): backfill pr 2108 for #2087 changeset
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 17:38:30 -04:00
Tom Boucher
396f44bd0b feat(architecture): [EoS/opencode] Migrate OpenCode onto the Embeddable Orchestration System (ADR-1239, #2087)
Route OpenCode (and its Kilo sibling) through the public Host-Integration Interface and
land two Context7-verified capability upgrades. Byte-identical install output for all 16
runtimes (golden parity asserted).

Through the interface (AC2):
- OpenCode/Kilo's bespoke commands+skills+plugin install (the inline
  `else if (isOpencode || isKilo)` block) moves into the engine
  (installOpencodeFamilyCommands/Artifacts in src/install-engine.cts), dispatched by
  installRuntimeArtifacts when the descriptor declares hostBehaviors.combinedFamilyInstall.
  opencode/kilo now flow CLI -> _runtimeAdapter -> installRuntimeArtifacts like the skills
  runtimes. _isSkillsRuntime no longer excludes them; the bespoke block + dead
  copyFlattenedCommands are removed.
- Every hardcoded `runtime === 'opencode'`/`isOpencode` branch is folded into
  descriptor-driven runtime.hostBehaviors. ZERO `runtime === 'opencode'`/`'kilo'`
  string-equality remain in bin/install.js / install-engine.cts / runtime-artifact-conversion.cts.

Upgrades (AC4):
- Background dispatch: OpenCode shipped experimental background subagents in v1.15 and
  made them default-on in v1.17 -> dispatch.background/backgroundDispatch flip to true;
  shouldFlattenDispatch(opencode) now returns false (behavioral change; type: Changed).
- Expanded event surface: the OpenCode plugin subscribes permission.asked/replied +
  session.error.

Tests: opencode-imperative-reference (adapter/profile, shouldFlattenDispatch pin,
fail-closed negotiate, hostBehaviors, AC2 source-guard) + extended plugin surface test.
Docs: capability matrix v1.15/v1.17 citations. Changeset (Changed). gitignore .memdb//.memtrace/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 17:17:05 -04:00
Tom Boucher
e0f245a6b2 fix(#2073): regen claude-local golden; reword changeset (no product parenthetical) 2026-07-08 17:15:48 -04:00
Tom Boucher
01a8fc94a6 docs(changeset): add Fixed fragment for #2073 agy reviewer hardening 2026-07-08 16:47:02 -04:00
Tom Boucher
7abe6e34ac chore(#2073): regen workflow-size baseline for review.md growth
The agy block grew (~file-reference prompt instruction, external-timeout
rationale, --model wiring, richer Step 3 diagnostic) — all load-bearing
content fixing 3 production failure modes (#2073), not bloat. Growth
justified in the PR.
2026-07-08 16:47:02 -04:00
Tom Boucher
6ae23ffc21 fix(#2073): supersede #687 contract; regen golden install-parity baselines
#687 encoded 'agy bounded ONLY by --print-timeout, no external killer' and
'inline -p "$(cat)"'. Documentation since then (see PR description) shows:
  * agy's own print-mode guidance pairs --print-timeout with an external
    terminal 'timeout' (it cannot fire pre-session);
  * agy gained --model in ~1.0.3 (#3782's 'no --model' note was correct then,
    stale now);
  * inline "$(cat)" overflows the exec arg list on a large review prompt.
Rewrite the #687 describe block to the new contract (file-reference prompt +
--print-timeout PAIRED with a >= external timeout + --model + discard-on-
nonzero), and regenerate the 16 golden install-parity fixtures (only the
review.md hash line changed per runtime).
2026-07-08 16:47:02 -04:00
Tom Boucher
af9069f865 fix(#2073): harden agy reviewer block (arg overflow, 404, pre-session stall)
Three failure modes on agy 1.0.16, all fixed by mirroring the Cursor block's
invocation discipline:
  * file-reference prompt instead of inline "$(cat)" — a large review prompt
    overflowed the exec arg list (rc 126).
  * external 'timeout 600' wrapper — --print-timeout cannot fire before agy
    creates a session, so a pre-session stall hung unbounded.
  * --model from review.models.agy when set — escape hatch for a pinned model
    that 404s (exit 0, empty stdout + transcript).
  * stdin </dev/null so agy never blocks on a tty.
Also enrich the Step 3 empty-output stub to grep agy cli.log for a
model-availability diagnostic, and correct the stale 'no --model flag' note
plus the 'review.models.agy reserved for future' comment (the config key was
already read but never passed through).
2026-07-08 16:47:02 -04:00
Tom Boucher
6dc4676d92 test: add failing regression for #2073 agy reviewer invocation shape
The agy block in /gsd-review overflows the exec arg list (inline "$(cat)"),
has no external timeout (pre-session stall hangs past --print-timeout), no
--model escape hatch for a 404'd pinned model, a generic empty-output stub,
and a stale 'no --model flag' note. These tests pin the corrected shape in
gsd-core/workflows/review.md; they fail on next.
2026-07-08 16:47:02 -04:00
Tom Boucher
ab78797ac5 Merge pull request #2106 from open-gsd/feat/2086-eos-claude-imperative-adapter
feat(#2086): [EoS/claude] Migrate Claude Code onto the Embeddable Orchestration System (ADR-1239)
2026-07-08 15:47:47 -04:00
Tom Boucher
eeec6b512e fix(#2086): AC2 source-guard must ignore comments/backtick prose, not just code
The #338 fail-safe commit added a comment containing the literal `runtime === 'claude'`
(explaining what the data lookup is NOT), which the AC2 source-grep test matched as a
false positive (the test read the whole file, prose included). Strip block/line comments
+ backtick spans before matching so the guard flags only LIVE code, and reword the
comment. CRLF-safe line-comment strip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 15:26:19 -04:00