Skip to content

refactor(ci): restore zombie-import gate + narrow acp/runtime pattern + rebaseline (#2355)#2454

Merged
alexey-pelykh merged 1 commit intomainfrom
ci/2355-restore-h3-clean-allowlist
Apr 21, 2026
Merged

refactor(ci): restore zombie-import gate + narrow acp/runtime pattern + rebaseline (#2355)#2454
alexey-pelykh merged 1 commit intomainfrom
ci/2355-restore-h3-clean-allowlist

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

Restore ADR 0005 H3 (PR #2357) after it was reverted by the v2026.3.7→v2026.3.8 upstream sync (PR #2360, fc2cefeeab). The sync rolled scripts/check-no-zombie-imports.mjs back to its pre-H3 hardcoded form, orphaning the JSON allowlist and baseline files H3 introduced.

This is ironic: the exact sync-regression class ADR 0005 was designed to prevent struck the ADR's own enforcement infrastructure. H10's composite sync-PR audit (PR #2447, merged 2026-04-21) would have caught this — but it didn't exist when #2360 merged.

Changes

1. Restore H3 gate script

Re-apply af4169bf9a three-part reform to scripts/check-no-zombie-imports.mjs: registry-derived deadModulePatterns from scripts/data/tombstones.json, JSON allowlist loader, tombstone existence scan, baseline comparison, and resolveRepoRootFromScript() (fixes the pre-H3 scan-zero-files bug).

2. Narrow acp/runtime fallback pattern

Split broad acp/runtime into acp/runtime/session-meta + acp/runtime/session-identifiers (the only 4-line stubs). The broad pattern was catching legitimate imports from the live public plugin-sdk API:

File Live? Size
src/acp/runtime/errors.ts Live (AcpRuntimeError, error codes) 61 LOC
src/acp/runtime/registry.ts Live (runtime backend registry) 112 LOC
src/acp/runtime/types.ts Live (AcpRuntime types) 138 LOC
src/acp/runtime/session-meta.ts Stub 4 LOC
src/acp/runtime/session-identifiers.ts Stub 4 LOC

Narrowing eliminates 11 false positives from src/plugin-sdk/acpx.ts and src/plugin-sdk/index.ts.

3. Rebaseline allowlist JSON (68 → 23 entries)

Cleanup class Count
Stale entries removed (line drift during H3 offline period) 42
False-positive entries removed (post-narrowing) 11
Previously-unallowed violations retained 8
Retained pre-existing 15
Final 23

4. Decrement baselines

5. Remaining 23 entries by pattern

Pattern Count Class
agents/model-selection 13 Pending gutting per MBP (file has live H9-attested functions but should be gutted); follow-up gutting issue to be filed
agents/sandbox 7 Truly gutted; each entry requires migration
acp/runtime/session-meta 3 4-line stub; callers need migration
agents/skills 1 Truly gutted; migration required

Why agents/model-selection is KEPT in fallback

src/agents/model-selection.ts has live functions declared via H9 MODULE_ATTESTATIONS (resolveConfiguredModelRef, resolveDefaultModelForAgent, etc.). These are NOT gate false positives — they're gutting debt per the Middleware Boundary Principle (CLI agents own model selection, not middleware). The 13 tracked imports surface that this file should be gutted in a follow-up PR. Keeping the broad pattern ensures the gate catches any new imports of these functions.

Verification

  • node scripts/check-no-zombie-imports.mjs → Zombie-import gate passed. 36 tombstones, 45 patterns (36 derived + 9 fallback), 23 allowlisted callsites.
  • pnpm format → clean (5116 files)
  • pnpm tsgo → Exit 0
  • pnpm lint → 0 warnings / 0 errors (3933 files)
  • Sibling gates (check-stub-debt, check-obsolescence-audit, check-throwing-stub-callers) → confirmed no sync regression

Test plan

  • Zombie-import gate passes locally
  • Format, type-check, lint all pass
  • Sibling H5-H10 gates verified unaffected
  • CI verifies no regressions across full workflow

Follow-ups

🤖 Generated with Claude Code

… + rebaseline allowlist (#2355)

Restore ADR 0005 H3 (PR #2357) after it was reverted by the
v2026.3.7→v2026.3.8 sync (PR #2360, `fc2cefeeab`), which rolled
`scripts/check-no-zombie-imports.mjs` back to its pre-H3 hardcoded form
and orphaned the JSON allowlist + baselines.

Changes:

1. Restore H3 gate script with registry-derived `deadModulePatterns`,
   JSON allowlist loader, tombstone existence scan, and baseline
   comparison — identical to `af4169bf9a` minus the targeted narrowing
   in point 2.

2. Narrow `acp/runtime` fallback pattern: split broad `acp/runtime`
   into `acp/runtime/session-meta` and `acp/runtime/session-identifiers`
   (the only 4-line stubs in that namespace). `acp/runtime/errors`,
   `acp/runtime/registry`, and `acp/runtime/types` are live public API
   re-exported by `src/plugin-sdk` — the broad pattern was catching
   them as false positives.

3. Rebaseline allowlist JSON from 68 → 23 entries:
   - 42 stale entries removed (line drift during H3's offline period)
   - 11 false-positive entries removed post-narrowing
   - 8 previously-unallowed new violations retained
   - Remaining 23: 13 `agents/model-selection`, 7 `agents/sandbox`,
     3 `acp/runtime/session-meta`, 1 `agents/skills`

4. Decrement baselines:
   - `.zombie-import-allowlist-baseline`: 71 → 23
   - `.zombie-tombstone-baseline`: 12 → 0 (all tombstoned files already
     absent; #2356 is auto-satisfied)

`agents/model-selection` broad pattern is KEPT despite the file having
live H9-attested functions — those are pending gutting per the
Middleware Boundary Principle, tracked debt rather than gate false
positives. Follow-up gutting issue to be filed.

Gate passes locally: `Zombie-import gate: 36 tombstones, 45 patterns,
23 allowlisted callsites. Import scan: clean.`

Refs: ADR 0005 H3 (engineering/decisions/0005-fork-sync-hardening.md)
Regression source: #2360 (sync v2026.3.7→v2026.3.8)
Auto-satisfied: #2356 (0 tombstoned files exist)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexey-pelykh alexey-pelykh enabled auto-merge (squash) April 21, 2026 14:06
@alexey-pelykh alexey-pelykh merged commit 08b3a43 into main Apr 21, 2026
15 checks passed
@alexey-pelykh alexey-pelykh deleted the ci/2355-restore-h3-clean-allowlist branch April 21, 2026 14:12
alexey-pelykh added a commit that referenced this pull request Apr 21, 2026
…tion per MBP (#2455)

Delete src/agents/model-selection.ts (170 LOC) per Middleware Boundary
Principle. Model selection is owned by CLI runtimes (Claude, Gemini, Codex,
OpenCode); middleware only reads the configured default from cfg.agents.defaults.

Live config-reading utilities relocated to src/agents/provider-utils.ts
(their natural home alongside existing provider normalization + model ref
parsing helpers):
- buildModelAliasIndex
- resolveConfiguredModelRef
- resolveDefaultModelForAgent
- ModelAliasIndex type

Dead stubs eliminated (zero production callers):
- resolveModelRefFromString (only the test-mock consumed it)
- resolveThinkingDefault (always returned undefined; caller block in chat.ts
  was unreachable — removed)
- getModelRefStatus (always returned undefined)
- inferUniqueProviderFromConfiguredModels (always returned undefined; caller
  block in session-utils.ts was unreachable — removed)
- splitTrailingAuthProfile (internal helper; only served resolveModelRefFromString)

14 callers migrated (issue listed 13 + 1 phantom; this PR additionally covered
provider-capabilities.ts, transcript-policy.ts, and get-reply.test-mocks.ts
which were missed by the issue's path-qualified grep):
- Category A (re-export redirects): agent-runner, directive-handling.model-picker,
  session-store, defaults, gateway-cli-backend.live.test, provider-capabilities,
  transcript-policy
- Category B (type relocation): directive-handling
- Category C (live-function callers): status.summary, sticker-cache, session-utils,
  chat (imports dropped + dead thinkingLevel fallback removed)
- Category D (test mocks): agent.test (with modelSelectionModule →
  providerUtilsModule rename), run.test-harness (mock retarget + stale mock
  helpers removed), get-reply.test-mocks (dead vi.mock block removed)

Zombie-import gate updated:
- scripts/check-no-zombie-imports.mjs: removed "agents/model-selection" from
  fallbackDeadModulePatterns + explanatory block
- scripts/data/zombie-import-allowlist.json: -12 entries
- .zombie-import-allowlist-baseline: 23 → 11

Baselines self-healed:
- .fork-boundary-mock-baseline: 133 → 132 (direct: removed vi.mock in
  get-reply.test-mocks.ts)
- .obsolescence-baseline: 134 → 49 (this PR: -1; pre-existing unbaselined
  improvements: -84 — verified via stash-based pre-change gate run)

Sibling precedents: #2414 (Discord model-picker gut), #2449/#2451 (Mattermost
model-picker gut). Surfaced during #2454 H3 restoration; closes #2355 debt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
alexey-pelykh added a commit that referenced this pull request Apr 21, 2026
…tion per MBP (#2455) (#2456)

Delete src/agents/model-selection.ts (170 LOC) per Middleware Boundary
Principle. Model selection is owned by CLI runtimes (Claude, Gemini, Codex,
OpenCode); middleware only reads the configured default from cfg.agents.defaults.

Live config-reading utilities relocated to src/agents/provider-utils.ts
(their natural home alongside existing provider normalization + model ref
parsing helpers):
- buildModelAliasIndex
- resolveConfiguredModelRef
- resolveDefaultModelForAgent
- ModelAliasIndex type

Dead stubs eliminated (zero production callers):
- resolveModelRefFromString (only the test-mock consumed it)
- resolveThinkingDefault (always returned undefined; caller block in chat.ts
  was unreachable — removed)
- getModelRefStatus (always returned undefined)
- inferUniqueProviderFromConfiguredModels (always returned undefined; caller
  block in session-utils.ts was unreachable — removed)
- splitTrailingAuthProfile (internal helper; only served resolveModelRefFromString)

14 callers migrated (issue listed 13 + 1 phantom; this PR additionally covered
provider-capabilities.ts, transcript-policy.ts, and get-reply.test-mocks.ts
which were missed by the issue's path-qualified grep):
- Category A (re-export redirects): agent-runner, directive-handling.model-picker,
  session-store, defaults, gateway-cli-backend.live.test, provider-capabilities,
  transcript-policy
- Category B (type relocation): directive-handling
- Category C (live-function callers): status.summary, sticker-cache, session-utils,
  chat (imports dropped + dead thinkingLevel fallback removed)
- Category D (test mocks): agent.test (with modelSelectionModule →
  providerUtilsModule rename), run.test-harness (mock retarget + stale mock
  helpers removed), get-reply.test-mocks (dead vi.mock block removed)

Zombie-import gate updated:
- scripts/check-no-zombie-imports.mjs: removed "agents/model-selection" from
  fallbackDeadModulePatterns + explanatory block
- scripts/data/zombie-import-allowlist.json: -12 entries
- .zombie-import-allowlist-baseline: 23 → 11

Baselines self-healed:
- .fork-boundary-mock-baseline: 133 → 132 (direct: removed vi.mock in
  get-reply.test-mocks.ts)
- .obsolescence-baseline: 134 → 49 (this PR: -1; pre-existing unbaselined
  improvements: -84 — verified via stash-based pre-change gate run)

Sibling precedents: #2414 (Discord model-picker gut), #2449/#2451 (Mattermost
model-picker gut). Surfaced during #2454 H3 restoration; closes #2355 debt.

Co-authored-by: Claude Opus 4.7 (1M context) <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.

chore: delete 12 tombstoned files surviving from v2026.3.7 sync

1 participant