feat(lint): adapter-call-site lint for mag.orchestration YAML keys (gh-ludics-496)#500
feat(lint): adapter-call-site lint for mag.orchestration YAML keys (gh-ludics-496)#500
Conversation
|
@codex review Focus on bugs, correctness issues, and edge cases. Do not check adherence to a spec or plan. |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Adds a regex-over-source extractor that returns the set of literal first-segment keys read from `orchCfg` in a single adapter source file (src/adapters/t3code.ts or src/adapters/tmux-adapter.ts). Strips JSDoc / block / line comments before matching so a `// orchCfg.foo` mention does not silently satisfy coverage for an unimplemented key. Mirrors the SILENT-DRIFT WARNING shape from extractMagPathsFromSource (gh-ludics-406) — the wrap-it-behind-a-helper failure mode is the same; the floor-count and zero-match self-test are the same mechanical guard. Floor-count tests today: t3code 11 distinct keys (floor 9 with slack), tmux-adapter 8 distinct keys (floor 6 with slack). Plus a motivating-keys test that pins both phase_timeouts and substantive_stall — if either drops out of the live extractor, the lint that's about to be wired up in scripts/lint-config-reference.ts stops covering its own precipitating failure class (task-a670cdbf round-2 review of PR #493). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…cs-496)
Wires `extractAdapterReadKeysFromSource` through `runLint`. The new
direction enumerates the first-segment keys documented under
`mag.orchestration:` in templates/config.reference.yaml and asserts
that each is read by at least one of src/adapters/t3code.ts or
src/adapters/tmux-adapter.ts. Disjunctive coverage matches reality
— `default_mode`/`default_coder`/`default_reviewer` are t3code-only
concepts, and tmux's coverage is otherwise a strict subset.
`RunLintResult` gains two arrays. `inertYamlKeys` lists documented
leaves with no adapter read; `inertSelfTestErrors` fires when either
adapter file's extractor returns the empty set, so a future DRY
refactor that hides every `orchCfg?.<key>` literal behind a helper
fails loudly rather than silently passing the lint at zero coverage.
The two arms are kept distinct so a complete extractor miss is not
misdiagnosed as every YAML key being inert.
`IGNORE_ADAPTER_READ` bootstraps as the empty Set: every current
mag.orchestration: leaf is covered (verified by the live
`bun run lint:config-reference` pass).
Test scaffolding: `makeFixture` now backfills minimal
`const _ = orchCfg?.foo;` stubs into `src/adapters/{t3code,tmux-
adapter}.ts` for every fixture, so existing TS↔YAML / harness-subset
tests don't trip the new self-test arm. The five new
adapter-direction E2E tests override the stubs with explicit content
to pin AC3 (disjunctive), AC4 (first-segment over substantive_stall.*),
AC5 (zero-match self-test), and the AC8 happy/inert pair.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…496) Both entries cite task-a670cdbf round-2 review of PR #493 as the precipitating retro: 1. "New OrchestrationConfig fields require parse+merge in adapter init" — names the four surfaces (interface, default, migrateState backfill, adapter parse+merge) and the shared-parser pattern; closed mechanically by the lint shipped in the sibling commits. 2. "'Adapter init reads YAML' is a separate AC for OrchestrationConfig field additions" — flags the AC-bundling anti-pattern that hides the YAML-read step under "config field exists". Both are competent-SWE-filter "obvious-to-experienced-engineer" items that survive deadline pressure across distant surfaces. Captured to the textbook's write-side memory rather than promoted to always-loaded coder/reviewer prompts (per AC11/AC12 negative control). AC9 idempotency: pre-append snapshot evaluation showed all three guard checks (both headlines, shared retro) miss against the existing seed entry; post-append self-check shows all three hit. Shape regression test in docs/swe-textbook.shape.test.ts pins each new headline + retro citation under the existing slice helpers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
641344a to
78cb251
Compare
Suggest Refactor (coder retrospective for #500 / gh-ludics-496)What I'd do differently next time, in order of bite:
What worked well and shouldn't change:
|
Summary
lint:config-referencewith a fourth direction that asserts every documentedmag.orchestration.<leaf>key intemplates/config.reference.yamlhas at least one literal read site insrc/adapters/t3code.tsorsrc/adapters/tmux-adapter.ts— closing the silent-inert-key class flagged by PR Split settled-no-signal vs hung detection (task-a670cdbf) #493 round-2.extractAdapterReadKeysFromSourcehelper inscripts/lint-config-helpers.tsstrips comments before regex so// orchCfg.future_keymentions cannot satisfy coverage. Floor-count + zero-match self-test guards mirror the gh-ludics-406 SILENT-DRIFT doctrine.docs/swe-textbook.md(write-side memory; AC11/AC12 negative controls keep the file out of always-loaded coder/reviewer prompts).Closes #496.
Test plan
bun test scripts/lint-config-helpers.test.ts— 32 pass (6 new underextractAdapterReadKeysFromSource)bun test scripts/lint-config-reference.test.ts— 13 pass (5 new under the adapter-call-site direction)bun test docs/swe-textbook.shape.test.ts— 26 pass (3 new under the gh-ludics-496-entries describe block)bun run lint:config-referenceagainst the live tree — exit 0, no inert keys, no self-test errorsbun run typecheck— cleanbun test— 2243 pass / 0 fail (baseline 2228 + 15 new)git grep -F "swe-textbook"in agent-loaded skills both empty🤖 Generated with Claude Code