Skip to content

Core hardening tracker: converge duplicated runtime invariants onto single owners #104219

Description

@obviyus

Summary

Tracker for a bounded core-hardening effort: replace competing implementations of the same runtime invariant with one canonical owner and one execution path. Started from an AI-assisted architecture comparison (cross-checked against OpenAI Codex CLI's structure), verified per seam with file-level evidence before each change.

Outcome: complete. Seven PRs merged. A mid-effort re-verification (2026-07-12, fresh code reading of every remaining row against current main) falsified or downgraded most of the remaining claims — those rows were dropped rather than built.

Change shape (per seam)

  1. Identify the earliest correct owner.
  2. Encode the decision as one closed typed fact, result, descriptor, or state transition.
  3. Carry that result forward instead of rediscovering it downstream.
  4. Delete parallel maps, state machines, waiters, classifiers, name lists, aliases, and fallback paths in the same change.
  5. Prove the canonical path through focused tests and the normal user/runtime flow.

Results

# Seam Outcome
1 Agent job lifecycle #104147 merged — one terminal registry and one wait path; net −358 prod LOC, agent-wait-dedupe.ts deleted
2 Core tool factory ownership #104213 merged — typed tool-family catalog; fixed real allowlist drift (transcripts omitted, canvas misclassified)
3 CLI-runner terminal reasons #104319 merged — one shared derivation backed by agent-run-terminal-outcome.ts
4 Run-registry staleness policy #104476 merged — one staleness policy imported by both registries instead of hand-copied 10-min constants
5 Error → user-facing classification #104546 merged — chat error badge maps canonical failover reasons; detectErrorKind deleted from core (kept as deprecated plugin-SDK compat). Remaining "duplicate classifiers" turned out to answer different questions with deliberate policies — dropped
6 Tool behavior name lists Dropped — the claimed bash/exec drift causes zero wrong behavior (alias normalization or dual-listing neutralizes it in all four lists; pinned by an existing test)
7 attempt.ts finalization epilogue Deferred — no live drift; hottest file in the runner (140 commits in 2026), so a structural rewrite is pure regression risk. Revisit only if epilogue bugs recur
8 Session store accessor bypass #104880 merged — most bypasses were already rerouted upstream (#98236, #101179); the last non-doctor caller (get-reply-run.ts) moved to accessor per-entry APIs. Remaining debt is owned by the session-accessor-debt-baseline ratchet
9 Provider identity/setup metadata Narrowed — manifest↔runtime literal duplication is intentional layering (manifest-first cold control plane); the real exposure was the missing parity check → row 12
10 Subagent authority Dropped — persisted role can disagree with depth after a maxSpawnDepth change, but the spawn gate independently checks raw depth, so it is non-exploitable; the depth fallback is required for legacy records
11 Session row type mirror Dropped — GatewaySessionRow is an intentional view-model projection, not a drifting mirror; the files co-evolve correctly
12 Hardening batch (from 9 + 5 residue) #104886 merged — CORE_BUILT_IN_MODEL_APIS single-sourced; fail-closed 72-case manifest↔runtime auth-literal parity test (drift here = silent auth failure); terminal catch honors structured FailoverError reasons (context_overflow, timeout/server_error), accepted via maintainer proof override — live paths proven regression-free, tokenless case unit-pinned

Takeaway

Duplication tracks shape openness, not codebase size: where an owner exports a closed type, downstream layers delegate; where it exports open shapes — boolean flags, freeform strings, name lists — shadow reimplementations accrete above it. Convergence only sticks when the PR both exports the closed type and deletes the superseded path in the same change. The second lesson is from the re-verification: half the plausible-looking seams dissolved under fresh code reading — "two code sites computing the same-looking thing" is often two deliberate policies answering different questions, and unifying them is a regression dressed as cleanup. Verify drift consequences, not drift appearance, before building.

Remaining follow-ups (own decisions, not this tracker)

  • Plugin-SDK whole-store session API: plugin-sdk/session-store-runtime.ts and the library.ts root exports still publish loadSessionStore/updateSessionStore as shipped API — retiring them is a compatibility-sensitive SDK decision.
  • Seam 7 (attempt.ts terminal epilogue) if terminal-ordering bugs recur there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.enhancementNew feature or requestimpact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maintainerMaintainer-authored PRmaturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions