Two lifecycle holes the registry and the consumer helper left open.
`AdapterRegistrationHandle.replace` had no liveness guard: after the handle's
disposer ran, a replace put routes back into the registry with nothing left to
release them, so the adapter leaked permanently. `owned` being empty cannot
carry that fact, because `replace([])` is the legal empty-section state, so the
disposer records it explicitly.
`installSettingsSection`'s watcher lacked the guard its own disposer carries:
a stored change landing while the consumer unloads reached `onChange`, which
re-registers routes against a fiber whose resources are being released.
Also documents `withFileLock` in the atomic-write README (it claimed one
export), records the age-based lock takeover as a known limitation, and lists
ctx.settings and ctx.credentials in the architecture capability table.
The master merge moved the TUI composition into `apps/cli/config/base.cordis.yml`
and I carried the `settings-local` / `credentials-local` rows across without
adding them to the resolver manifest. Bare specifiers in an app config resolve
through that manifest's dependencies, so the whole tree failed to boot:
dsh: plugin(s) failed to load: @deepseek-ai/dsh-settings-local,
@deepseek-ai/dsh-credentials-local
which took every TUI PTY smoke with it. `verify-cordis-config` did not catch
it, so the boot smoke was the first signal.
Review follow-up. provenLocalCallee inferred file-local calls from module
scoping but borrowed non-exportedness from its one caller and never checked
module-ness: a helper in a global script file (no import/export) is
program-visible and callable cross-file with no same-file reference, so the
proof passed and those call sites were dropped as silently missing matrix
cells. Guard both premises at the proof entry, failing toward the global
fallback.
- State the EVENT_API_METHODS obligation: a visitSource branch for an
unlisted method name is dead because the prefilter drops the call first.
- Add gen-doc-graphs.spec.ts pinning fast path vs global fallback equivalence
on fixture programs: a proven-local helper, an alias-escaping helper, and a
global-script helper (negative control that keeps the fallback exercised).
- Record the demand-driven indexing decision in the Program-backed semantic
gates Agent Note (both languages, pairing re-recorded).
Generated docs stay byte-identical (verify-doc-graphs green).
The event-relation collector resolved every CallExpression in all package
sources up front (getResolvedSignature is the most expensive checker query)
and type-classified every property-access receiver before looking at the
method name. Both costs served a tiny fraction of call sites.
- Filter by event API method name first; receiver classification now runs
on those calls only.
- Replace the eager global call-site index with demand-driven indexing:
when a non-exported local helper's same-file references are all provably
direct callees, only that file is indexed; any other reference shape
(alias escape) falls back to the original full package-source index.
Generated docs are byte-identical; verify-doc-graphs stays green. Halves
the script's CPU time (23.4s -> ~13s user on a warm run).