Commit graph

2407 commits

Author SHA1 Message Date
Peter Steinberger
5697a7277a
fix(agents): use exact model rows for harness support (#147849)
Keep API, endpoint, and request override facts tied to the selected configured model. Reuse the existing configured-row resolver and remove duplicate prefix stripping and normalized-row merging from harness support.

Preserve literal legacy selection, legacy-only fallback, and same-spelling duplicate semantics. Registered-harness regressions fail in both conflicting row orders before the fix; 203 focused tests, the changed-file gate, and independent review pass.

Related: #130706, #143822.
2026-09-13 21:59:55 -07:00
Peter Steinberger
d46f9ebf2b
fix(memory): explain partial search timeouts and allow 30 seconds (#147702) 2026-09-13 19:34:11 -07:00
Peter Steinberger
f8b194a5be
fix: restore plugin networking under Bun (#147421)
* fix(plugins): normalize network runtimes

* build(plugins): align network runtime dependencies

* test(runtime): stabilize network compatibility checks

* fix(codex): route managed transports through runtime owners
2026-09-13 19:25:19 -07:00
Peter Steinberger
cc5a7467f9
fix(tasks): record execution ownership and settle orphaned records at restore (#147585)
* fix(tasks): settle orphaned execution records at restore

Record nullable process ownership for Gateway runs and local native harness
processes. Settle confirmed dead owners through the existing restart outcome
normalizer before restored tasks can block another drain. Preserve live,
foreign-host, unknown, and legacy ownership.

Add compatible nullable SQLite columns without changing the schema version.
Reported by @gregbond (#143420).

* fix(tasks): keep unchanged restores read-only

Request write admission only when restored state contains a confirmed orphan,
then reread and revalidate ownership before persisting settlement. Preserve
existing create/delete admission-failure semantics and cover a concurrent
owner rebind.

List the three approved nullable ownership columns in the canonical additive
schema contract test without relaxing its declaration checks.

* fix(tasks): preserve newer flow results during restore

Synchronize a restored orphan's mirrored flow only when that task is the
latest linked record. Keep newer live and completed successors' status,
goal, and terminal timestamps while still settling the orphaned task.

Cover both mixed-owner cases through the registry restore boundary.
2026-09-13 19:08:26 -07:00
Vincent Koc
3a99779313
fix(codex): isolate hook imports and cancel disconnected waits (#147444)
Isolate the native hook relay build graph while preserving readonly state lookup, explicit policy decisions, and the lazy authenticated Gateway fallback.

Cancel disconnected request waits through the existing approval authority. Keep duplicate callers independently cancellable, retain unbound durable approval deduplication, and detach exact relay-owned entries before callbacks so old cleanup cannot remove a successor. Observe already-started promises when synchronous cancellation wins.

Update managed Codex to the official 0.154.0 release and align its version fixtures and current documentation. This improves lifecycle ownership and reduces the relay import closure; it does not cap hook concurrency, prove faster bursts, or establish resolution of the historical constrained-host timeout.

Related: https://github.com/openclaw/openclaw/issues/91009

Thanks to @nvtoroy for the constrained-host captures and guarded opt-out evidence in https://github.com/openclaw/openclaw/pull/121668 and https://github.com/openclaw/openclaw/pull/111205. The opt-out proposal remains distinct and unimplemented by this change.
2026-09-14 07:14:04 +08:00
Peter Steinberger
cb9c7d992b
refactor(plugins): remove unused provider wizard option projection (#146695)
Keep setup choices on the canonical manifest/install-catalog flow and remove
the unused runtime option producer, private shape, and builder. Retain
provider choice resolution, model pickers, model-selected hooks, and public
provider types. Move repository-local test coverage to the surviving owners
and remove only the already-retired test-helper exports and documentation.

Include the canonical constrained-host lint prerequisite from
9229af2c9e (#146186), authored by
Peter Steinberger <steipete@gmail.com>. Its three files are preserved
byte-for-byte. This prerequisite is already upstream and is not counted
as cleanup production savings.

Validation: 57 focused functional cases, 76 lint-runner cases, and all 42
combined changed checks passed. The normal Linux gate selected five core
lint batches on the reported 4-CPU/15-GiB runner. A two-pass precommit
review found no P0-P2 issues. Prior diagnostic failures remain retained;
no full package-build or new peak-memory measurement is claimed.
2026-09-13 15:31:05 -07:00
Peter Steinberger
23b0cacfc5
fix(ui): hide deleted Beams immediately in the sidebar (#147460) 2026-09-13 15:12:48 -07:00
Peter Steinberger
dab1f08376
feat: give every plugin a compact chat activity icon (#147333)
* feat: give every plugin a compact chat activity icon

Separate package-owned activity SVGs from plugin identity artwork. Ship 154 defaults and seven exact tool overrides, preserving Echo and the progress claw. Include authenticated bounded delivery, safe mask rendering, packaging, and authoring guidance.

* test: declare Vite types for the activity asset browser test

* refactor: keep plugin artwork selection with catalog presentation facts

* test: scope activity browser types and simplify fixture copies
2026-09-13 13:49:51 -07:00
Peter Steinberger
2386efc05c
feat(code-mode): infer results from the requested action (#147291)
Some checks failed
Native App Locale Refresh / Refresh native vi (push) Blocked by required conditions
Native App Locale Refresh / Refresh native zh-CN (push) Blocked by required conditions
Native App Locale Refresh / Refresh native zh-TW (push) Blocked by required conditions
Native App Locale Refresh / Commit native locale refresh (push) Blocked by required conditions
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Waiting to run
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Blocked by required conditions
Plugin Init Scaffold Validation / Validate provider scaffold (push) Waiting to run
Plugin NPM Release / preview_plugins_npm (push) Waiting to run
Plugin NPM Release / Validate release publish approval (push) Blocked by required conditions
Plugin NPM Release / preview_plugin_pack (push) Blocked by required conditions
Plugin NPM Release / Preflight plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / Seal prepared plugin npm release (push) Blocked by required conditions
Plugin NPM Release / Trusted publisher OIDC exchange (push) Blocked by required conditions
Plugin NPM Release / publish_plugins_npm (push) Blocked by required conditions
Plugin NPM Release / verify_plugins_npm (push) Blocked by required conditions
Vitest Cache Warm / warm (linux) (push) Waiting to run
Vitest Cache Warm / warm (macos) (push) Waiting to run
Workflow Sanity / no-tabs (push) Waiting to run
Workflow Sanity / actionlint (push) Waiting to run
Workflow Sanity / generated-doc-baselines (push) Waiting to run
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / debian-installer (push) Has been cancelled
Website Installer Sync / linux-build-tools-failure (push) Has been cancelled
Website Installer Sync / linux-non-root (push) Has been cancelled
Website Installer Sync / Fedora installer (non-root) (push) Has been cancelled
Website Installer Sync / Fedora installer (root) (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
* feat(code-mode): infer action-specific tool results

* refactor(agents): simplify tool call id normalization
2026-09-13 13:33:49 -07:00
Vyctor H. Brzezowski
b45e2464f5
feat(workboard): add selection and bulk card actions (#144756)
* feat(workboard): add selection and bulk card actions

* test(workboard): cover retry after partial bulk edit failure

* build(workboard): refresh bulk action assets

* test(workboard): use the gateway request contract in bulk fixtures

* test(workboard): reuse the typed request fixture

* fix(workboard): guard bulk actions against stale cards

* fix(workboard): preserve revisions across linked bulk deletes

* fix(workboard): preserve card snapshots when applying delete receipts

* build: refresh Workboard browser assets

* test(workboard): await concurrent SQLite fixture cleanup
2026-09-13 17:11:35 -03:00
Vyctor H. Brzezowski
31c6862ff8
refactor(workboard): refine card and board editors (#144754)
* refactor(ui): refine Workboard card and board editors

* test(workboard): cover editor retry guidance and appearance resets

* fix(workboard): initialize column drafts before tracking edits

* refactor(workboard): mount appearance controls with editors

* build(workboard): refresh editor assets

* refactor(workboard): introduce assignment helpers with editors

* refactor(workboard): retire unused editor selection adapters

* test(workboard): introduce radio readiness checks with editors

* fix(workboard): preserve appearance updates and isolate emoji input

* fix(control-ui): preserve emoji composition in editors

* build: refresh Workboard browser assets

* test(workboard): adapt appearance fixtures to SQLite worker
2026-09-13 17:11:34 -03:00
Vyctor H. Brzezowski
c1258c0864
refactor(ui): share Workboard selection and appearance controls (#144748)
* refactor(ui): share agent and appearance controls

* style(ui): apply the pinned formatter to shared controls

* test(ui): keep shared control proof independent of Workboard details

* refactor(workboard): defer adapters to their first consumers

* fix(ui): hydrate shared avatars and apply appearance colors

* fix(control-ui): isolate appearance colors by component

* fix(ui): retain shared agent selection styles

* test(ui): await appearance glyph import before assertions
2026-09-13 17:11:33 -03:00
Peter Steinberger
cd1ff2a4d6
feat: load CDN libraries and fonts in widgets (#147265)
* feat: load CDN libraries and fonts in widgets

Share public static-resource origins across document, sandbox, and channel policies while keeping API access and native Gateway pins separate. Add visualization guidance for inline code explanations and persistent dashboards.

* fix: preserve local widget renderers in direct hosting

Keep document-approved same-origin renderer scripts available in the intersecting HTTP CSP. Cover stored and newly wrapped registered documents without granting API connections.
2026-09-13 12:50:45 -07:00
Peter Steinberger
21de1eaf75
fix(ui): remove floating customization button (#147245)
Keep plugin view selection and reload on the Plugins page. Render that page in the built-in workspace so operators can recover custom workspaces without a floating control.
2026-09-13 11:18:31 -07:00
Peter Steinberger
38fb08d04b
refactor(workboard): keep SQLite work off the Gateway event loop (#146976)
* refactor(workboard): run SQLite persistence in workers

Preserve board-scoped hydration and card-scoped notification reads while moving complete database operations to plugin-owned worker connection leases. Drain admitted work and retain retryable cleanup across service retirement and transport failure.

* test(workboard): preserve unclassified plugin routing coverage

* test(workboard): await persisted cleanup outcomes
2026-09-13 09:56:53 -07:00
Peter Steinberger
c456e000de
fix(google-meet): honor summary output paths (#147078)
Route artifact and attendance summaries through the existing output writer, preserving summary bytes, file modes, and explicit write failures. Remove the direct-stdout summary paths.
2026-09-13 07:55:10 -07:00
Peter Steinberger
60643b4d0b
fix(channels): keep replies working after hot config reloads (#147001)
Keep inbound channel replies working after hot config reloads when a long-lived plugin monitor retains its startup config. Shared reply dispatch now always selects the Gateway's committed model-runtime publication, preserving exact catalog isolation and publication waits without restarting the monitor.

The shipped optional usePublishedModelRuntime SDK argument remains accepted, deprecated, and ignored until the next SDK major. Standalone dispatch and explicit per-turn overrides retain their existing contracts; transport durability remains owned by channel ingress.

The low-level regression delivers before reload, fails on the original code after reload with PreparedModelCatalogConfigReplacedError, and passes after the fix. Focused dispatch and sibling tests, standalone runner fixtures, build, and changed-file checks passed. A synthetic Gateway/channel/HTTP-provider harness delivered two replies around reload with the same Gateway process and monitor; real WeChat and Windows coverage remains unproven.

Fixes #146854
Related: #145563

Reported by @sunhsiao (#146854). Reproduction discussion and regression shape from @Lidashi1025 and @BronyaZaychik0328 (#145563).
2026-09-13 06:31:50 -07:00
Peter Steinberger
e05d8b6c90
fix: admit borrowed memory writes through the agent database owner (#146760) 2026-09-13 04:12:26 -07:00
Peter Steinberger
0d1cf24318
fix: settle embedded transcript repairs before session cleanup (#146842)
* fix(agents): settle embedded transcript writes before cleanup

* test: supply session manager in prompt error fixtures
2026-09-13 02:53:07 -07:00
Ayaan Zaidi
b10035faa9
fix(backup): archive unmanaged SQLite files as opaque bytes (#146700)
## What Problem This Solves

An unrelated SQLite file with foreign-key violations could prevent every backup from completing.

## Why This Change Was Made

Whether an included file gets the live-database snapshot path is decided by exactly one mechanism at `src/commands/backup-resource-inventory.ts:336`, from the core set plus declared plugin resources. The online root snapshot supplies the registry used for discovery and traversal, so planning no longer needs a quiet write-ahead log.

## User Impact

Undeclared files survive backup unchanged with filename warnings. Foreign SQLite symbolic links that exceed the link-resolution limit (`ELOOP`), including loops, are skipped with a filename warning. Corrupt managed databases and unavailable plugin SQLite capabilities still stop publication.

## Evidence

- Pinned main `f0817f23e9`: the real CLI exits 1 on a structurally valid foreign database with a foreign-key violation and publishes no archive.
- Candidate `ce85d13530c4`: CLI create with verification, verify, and restore preserve seven foreign files and sidecars byte-for-byte, with one warning each. Corrupt core and unavailable plugin functions still refuse publication. Managed hardlinks include committed WAL data and restore identical images.
- Tested commit `37f9d97a9d65` (capture behavior unchanged): real CLI backup succeeds during 10 ms commits (309 rows during the 3.6-second run) and in the 100 ms control. Verify/restore retain identical valid root/alias images with writes committed during backup. The unrelated symlink loop is skipped with one warning and the archive restores successfully.
- The full architecture check passes with zero import cycles; five formatter/command tests pass. All 10 managed-refusal/older-schema command cases and changed-test checks pass. The separate macOS planning assertion noted below remains a baseline failure. Type checks and the test-partition check remain for CI.

## Compatibility

No schema, plugin fields, flags, or archive format change. Existing `backupResources` declarations define managed plugin data.

## Consumers

- `backup create`: preserves undeclared SQLite files and reports their filenames.
- `backup verify` and `backup restore`: treat files outside the captured core registry as opaque.
- `src/commands/migrate/apply.ts:26-41`: pre-migration backup now accepts unrelated foreign SQLite, returns only the archive path, and does not forward opaque warnings.
- Fleet backup: uses the shared archive metadata adapter to preserve independent hardlink entries without stalling.

- `formatBackupCreateSummary` moved unchanged to `src/commands/backup-summary.ts`; `src/commands/backup.ts` and `src/infra/backup-create.test.ts` import that owner.

census: generic formatBackupCreateSummary reviewed — 2 callers listed

## Invalidation

Ownership is frozen from the captured root registry for each backup; later registrations belong to the next capture. A plugin declaration changed after planning can be archived with payload classified by the earlier declaration.

## Contention

Registry discovery reads the online root snapshot before archive traversal. The 10 ms sustained-write test and 100 ms control both complete, verify, and restore successfully.

## Tests

- `backupCreateCommand`: all eight managed-refusal cases and both older-schema cases in `src/infra/backup-create.test.ts`; older-schema verification also uses `backupVerifyCommand`.
- `backupVerifyCommand`: all three opaque-file/sidecar cases in `src/commands/backup-verify.test.ts`.
- `backupCreateCommand` and `backupRestoreCommand`: opaque loop handling, declared/core loop refusal, and agent registration captured immediately before the root snapshot.

Those tables retain the complete case mapping, fixtures, and assertions. Source bytes are compared after capture or refusal and before the real outcome recorder runs; the recorder still runs unchanged. The unchanged macOS manifest-path assertion reproduces on base. The added source lines separate resource planning from captured ownership and preserve missing-root checks.

Thanks @clawputerlabs for the report.

Closes #144552.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-13 11:31:38 +05:30
Peter Steinberger
877f157740
fix(agents): retain session writes through database admission (#146732) 2026-09-12 22:58:55 -07:00
Peter Steinberger
44ea63fe35
refactor(tasks): move managed child linkage to shared worker (#146678) 2026-09-12 22:49:31 -07:00
Peter Steinberger
2716950abf
fix(plugins): reuse registrations with prepared metadata (#146703) 2026-09-12 21:42:32 -07:00
Peter Steinberger
f5d9acfa70
refactor: share Markdown table parsing for Teams (#146464) 2026-09-12 20:55:13 -07:00
Peter Steinberger
ee679bb785
fix(state): share agent write admission with trajectory producers (#146563)
* fix: keep I/O responsive during queued session writes

* test(telegram): await debounced dispatch completion

* fix(state): share agent write admission with trajectory producers

* fix(gateway): join worker event writes before acknowledgment
2026-09-12 20:51:53 -07:00
Peter Steinberger
e360372317
fix: avoid repeated catalog refreshes after slow discovery (#146665) 2026-09-12 20:02:37 -07:00
Peter Steinberger
f1c1f274ef
fix(session-share): hide subagents and tool activity (#146598)
* test(upgrade): assert explicit baseline plugin

* fix(session-share): hide subagents and tool activity

Publish only user and assistant conversation text from eligible root sessions. Preserve forks, redaction, read-only storage, and pagination; reject cursors from the previous mixed-item projection. Skip unrelated local adoption scans for publication-only catalog queries.
2026-09-12 18:19:41 -07:00
Peter Steinberger
a84d90b9c2
fix(models): reclaim plugin captures after catalog workers stop (#146513)
Give each catalog Worker a parent-owned capture directory. Release execution
at confirmed Worker exit and join detached advisory cleanup on pool close.
Preserve static Worker options, and fence synchronous cancellation during
preparation or construction before releasing ownership.

Make full-catalog test assertions follow the existing completed publication
after one bounded foreground request, preserving pending and cancellation
coverage and all production deadlines.
2026-09-12 17:31:32 -07:00
Peter Steinberger
1db6e89d4e
fix(gateway): release retired catalog waiters (#146498)
* fix(gateway): release retired catalog waiters

* refactor(gateway): separate catalog admission from provider results
2026-09-12 17:20:06 -07:00
Peter Steinberger
404387d910
feat(telegram): apply access and reply policy without reconnecting (#146129)
* feat(telegram): apply access and reply policy without reconnecting

* test(telegram): align retained-turn fixtures with extension contracts

* test(telegram): use typed reload policy keys

* fix(telegram): refresh ingress policy before cancellation
2026-09-12 17:11:10 -07:00
Agustin Rivera
b04aaad592
fix(nextcloud-talk): reject excess concurrent webhook reads (#146356)
* fix(nextcloud-talk): reject excess concurrent webhook reads

Acquire a listener-owned in-flight limiter slot before the unauthenticated
webhook body read, reject overflow with a close-aware HTTP 429, and release
the slot after signature verification but before authenticated dispatch.

Incomplete requests previously pinned a pre-auth reader for the full timeout
without consuming the authentication-failure budget, letting any reachable
client hold unbounded numbers of sockets and readers to degrade webhook
availability. This follows the owner-level pattern merged for SMS (#136504)
and Feishu (#137230).

* fix(nextcloud-talk): preserve queued acknowledgements under pipelined overflow

Serialize webhook admission per connection through the shared HTTP request
lifecycle (runHttpConnectionRequest, re-exported on the plugin SDK guards
subpath) so a pipelined request's overflow rejection only starts after every
earlier response on the connection finished. Covers the reviewed sequence with
real TCP: a saturated keep-alive connection with admission pending past the
one-second close timer must still deliver the earlier signed 200 before the
close-aware 429.

* docs(nextcloud-talk): document overload admission and SDK connection ordering

Record the 64-slot admission bound, its close-aware 429 overflow behavior,
ordered keep-alive acknowledgements, and the unverified sender-redelivery
risk in the channel guide. Document runHttpConnectionRequest's
response-completion and closure semantics for plugin-owned webhook
listeners on the SDK infrastructure page.

* docs(nextcloud-talk): correct overload mitigation guidance

The 64-read admission budget is hard-coded and not configurable, so raising
reverse-proxy connection limits cannot relieve saturation and can feed more
requests into the rejection path. Advise reducing or buffering upstream
concurrency instead, and state plainly that the budget is fixed.
2026-09-13 00:08:51 +00:00
Peter Steinberger
e7b868bbab
feat(voice): share GPT Live across meetings and calls (#146546)
* feat(voice): unify Live sessions across calls and meetings

Resolve provider capabilities and interruption policy through the shared realtime voice owner. Keep meeting input isolated from virtual-microphone output, reuse native delegation for meetings and Voice Call, and preserve explicit Stop across browser and Apple relay clients.\n\nValidated with real Live API and synthetic Chromium/WebRTC proof, focused regressions, changed-file checks, and independent review. Related to #146289.

* test(voice): align capture fixtures and validation gates

Model browser audio capture in the shared meeting RPC fixtures so startup
failure tests reach the provider and verify capture cleanup. Preserve the
same relay startup behavior while simplifying duplicate lifecycle branches.

Rebalance the pre-existing 702-root platform test graph by moving security
tests beside sandbox/tool tests; keep coverage, graph counts, and limits.

* fix(meetings): preserve configured input commands

Keep explicitly configured capture/filter/mixer output as provider input on
local Chrome and paired nodes, preserving the v2026.9.4 contract. Generated
input and output-only overrides continue to use managed browser capture.

Retain Live's isolation guard and explain how to remove an input override
when selecting Live. Prove the actual PCM paths through both meeting engines
and transports, and document the preserved configuration behavior.
2026-09-12 17:06:51 -07:00
Peter Steinberger
0be813c33d
fix(ui): make coding session discovery settings easy to find (#146502)
* fix(ui): surface coding session discovery controls

Add a sidebar shortcut and searchable session source settings for installed
Claude Code, Codex, OpenCode, and Pi plugins. Reuse the existing Gateway
configuration owner, including Pi's ACPX preference, and keep unavailable
schemas visible without permitting invalid edits. Preserve existing defaults.

* perf(ui): simplify session source menu navigation
2026-09-12 17:03:20 -07:00
Peter Steinberger
54a986072f
docs(plugins): remove obsolete Gateway restart guidance (#146516)
* docs(plugins): remove obsolete Gateway restart guidance

* docs(plugins): simplify apply hints and update Session Share guidance
2026-09-12 16:48:13 -07:00
Peter Steinberger
5b792cf8f3
refactor(tasks): move managed flow state changes to SQLite workers (#146495) 2026-09-12 15:01:15 -07:00
Peter Steinberger
82ab1e1f58
fix(qa): isolate gateway child supervisor state (#146397) 2026-09-12 14:48:45 -07:00
Peter Steinberger
2bfd953001
fix: await approval target persistence before completing delivery (#146325)
* fix: await approval target persistence before completing delivery

* fix(test): preserve aggregate extension routing
2026-09-12 13:50:54 -07:00
Peter Steinberger
5278a8f2ed
feat: share selected sessions read-only with a paired team Gateway (#136253)
* feat(node-host): advertise an explicit node command allowlist

Persist exact node command selection and restrict ancillary publication and hosting. Preserve the unchanged assertion baseline under the work-order stop rule; check:changed requests removing the obsolete runtime.ts count (2 to 0).

* feat(plugin-sdk): session transcript catalog reader

Expose bounded read-only native display pages and portable attribution through the existing runtime subpath. Keep pagination scoped to the original active transcript branch and allow an explicit bounded native cursor length.

* feat(session-share): read-only OpenClaw session catalog across paired gateways

Publish explicitly selected native session groups through two paired node commands. Validate the closed wire contract, reject remote profile claims, and keep receiver identity binding opt-in and display-only.

* fix(gateway): show published session catalogs to view-scoped roles

Let publication consent satisfy catalog read visibility for roles allowed to view others, while owner-only and unprofiled callers stay hidden. Preserve published attribution without accepting a remote local-session adoption claim. Regression tests reproduce four pre-fix failures; final validation stopped at the work-order baseline gate.

* docs: session sharing across gateways

Document sessions-only node setup, explicit publication groups, receiver attribution, view-scoped catalog access, and read-only limits. Add the bundled plugin inventory and generated reference entry. Live proof runbook remains outside the repository; build and rig execution are blocked by the work-order baseline restriction.

* fix(session-share): preserve source storage and paired reconnects

Respect configured stores through listing, paging, and revocation. Keep cold listings available and bound raw transcript reads. Prefer the established paired node credential on service restart, suppress unrelated host metrics, and refresh the approved plugin configuration docs.

* refactor(gateway): separate authorized catalog reads

Keep the catalog dispatcher within its owned scope and preserve post-read role checks and sender projection. Align the rebased tests with their shared setup and imports.
2026-09-12 13:35:17 -07:00
Peter Steinberger
1c2b861e6e
fix(auth): keep plugin auth available during provider discovery (#146336)
* fix(auth): keep synthetic auth discovery with its provider owner

Preserve auth-only descriptors and skip catalog-only matches before selecting a provider. Bound lightweight fallback to refs without a declared owner, so unrelated discovery failures cannot hide valid native auth or force unnecessary cold admission. Keep fresh external-auth capture and immutable plugin generation ownership intact.

* fix(auth): preserve provider match evaluation order

Match the provider reference before inspecting synthetic-auth hooks, preserving lazy descriptor selection while retaining the scoped discovery repair.
2026-09-12 13:33:58 -07:00
Peter Steinberger
d13f07b1c2
chore(deps): advance cooled dependencies and major upgrades (#146258)
* chore(deps): advance cooled dependencies and major upgrades

* test(logging): migrate failed-sink regression to tslog 5

* test: retain dependency upgrade coverage within lint limits

* fix(deps): preserve compiler launches, Matrix sync and chat metadata

Keep copied script harnesses independent of declaration modules and preserve
Windows executable prefixes after admission. Audit the Matrix sync guard for
42.3, align CI toolchain/cache pins, and refresh session facts after accepted
model-catalog invalidation without relying on picker timing.

* fix(ui): preserve scoped session reconciliation after catalog refresh
2026-09-12 13:28:12 -07:00
Peter Steinberger
a0cd0b8139
fix(discord): support continuous GPT Live conversations (#146289)
* fix(discord): support continuous GPT Live conversations

Reuse the Gateway-owned GPT Live bridge for Discord voice, preserve speaker-bound agent delegation, and let Live own interruption while microphone input remains admitted during playback. Pace input continuously, play short replies, and preserve queued speech pauses. Document model-specific voice routes and unsupported host turn policies.

* fix(discord): preserve live voice admission and defaults

Keep unpinned realtime configurations on their provider default, ignore silent RTP for speaker retention, and retain live-policy freshness through roster enrichment and agent dispatch. Cover policy revocation during the real participant lookup path, fresh and existing model defaults, and idle speaker reclamation.

* test(discord): isolate delegation admission coverage

Keep the unchanged native delegation admission cases in a focused suite so the voice receive tests remain within the repository file-size limit.

* test(voice): prove delegated agent authority and cancellation

* test(discord): await continuous playback completion
2026-09-12 13:17:52 -07:00
Peter Steinberger
fdf2853f48
fix(codex): restore native discovery and hide empty catalogs (#146305)
* fix(codex): restore native discovery and hide empty catalogs

Use the node native Codex home for listing, transcript reads, and terminal resume without requiring the Gateway agent on the node. Keep Gateway ownership for adopted Chats.

Use native authentication for catalog connections, preserve primary source fingerprints during recovery, and let native clients start without an OpenClaw agent. Keep managed inference auth requirements and existing node permission boundaries.

Hide empty sidebar catalogs while continuing normal discovery refreshes.

* test(ui): cover catalog errors beside available sessions

* fix(codex): preserve node compatibility and hidden catalog paging
2026-09-12 13:03:31 -07:00
Peter Steinberger
7b87a492ab
refactor: move shared database admission into its worker (#146172) 2026-09-12 12:58:11 -07:00
Peter Steinberger
e14b3ddac2
improve(memory): keep large-note searches responsive (#146168)
* fix: bound concurrent compute work and pending worker inputs

* fix: supply the host response budget in worker checkpoint tests

* fix: preserve prepared catalog ownership under admission pressure

* improve(memory): keep large-note searches responsive

* fix(memory): preserve worker errors and package boundaries

* docs: separate worker entrypoint guidance

* chore: align metadata extraction with main

* chore: align worker registration for main refresh

* fix(memory): unify metadata reads and worker registration

* fix(memory): preserve overload during index bootstrap and repair
2026-09-12 11:59:24 -07:00
Peter Steinberger
f47a0d4348
improve: avoid loading plugin state values for record counts (#146285) 2026-09-12 11:29:38 -07:00
Peter Steinberger
d72a144e7b
improve: keep image and PDF processing responsive (#146094)
* fix: bound concurrent compute work and pending worker inputs

* fix: supply the host response budget in worker checkpoint tests

* fix: preserve prepared catalog ownership under admission pressure

* improve: keep image and PDF processing responsive

* fix: register PDF worker declarations in build fixtures

* test: rebalance SQLite checks into the state shard

* fix: resolve workers in standalone plugin packages

* docs: separate worker entrypoint guidance
2026-09-12 10:58:14 -07:00
Peter Steinberger
63e204c2e5
fix: bound concurrent compute work and pending worker inputs (#146067)
* fix: bound concurrent compute work and pending worker inputs

* fix: supply the host response budget in worker checkpoint tests

* fix: preserve prepared catalog ownership under admission pressure
2026-09-12 09:24:25 -07:00
Ayaan Zaidi
d593351b13
fix(signal): refuse account deletion that activates a shadowed identity (#145981)
Deleting selected Signal row `collision-key` could report success and activate shadowed `Collision Key` after restart (#145750). The delete owner now rejects that takeover before effects, naming both keys. Unambiguous deletion works; dormant rows stay preserved.

The installed manifest is the single account-key policy declaration. Its snapshot reaches CLI/setup writers and post-write readers. Installation refreshes mutable operation facts while preserving callbacks and admitted Gateway inventory. Disabled owners retain maintenance policy; enabled-owner precedence stays intact. Reserved account IDs are rejected before setup writes.

The decision `whether a logical account survives deletion` is made by exactly one mechanism at `src/channels/plugins/config-helpers.ts:146`, which reruns `resolveChannelAccountKey` on the proposed remaining map.

## Consumers

S1–S36 bind every typed/manual location to its disposition. Coordinates are reviewed head `9a248139` or marked baseline; correction rows supersede relocated entries without erasing history.

The removed prepared API has no references; its `accountKey` duplicated the logical ID. The 74 remaining locations in 20 files have distinct contracts: Discord presence partitioning (`extensions/discord/src/monitor/presence-cache.ts`); Matrix storage identity and fixtures (`extensions/matrix/src/matrix/client/create-client.test.ts`, `extensions/matrix/src/matrix/client/create-client.ts`, `extensions/matrix/src/matrix/client/storage.ts`, `extensions/matrix/src/matrix/client/types.ts`, `extensions/matrix/src/storage-paths.ts`); Signal compatibility cleanup and reply-author partitioning (`extensions/signal/src/config-compat.ts`, `extensions/signal/src/reply-authors.ts`); WhatsApp group paths (`extensions/whatsapp/src/group-config-path.ts`); selected raw keys for field clearing, allowlists, setup, account config, and group policy (`src/channels/plugins/config-helpers.ts`, `src/channels/plugins/helpers.ts`, `src/channels/plugins/setup-helpers.ts`, `src/config/channel-account-config.ts`, `src/config/group-policy.ts`, `src/config/group-policy.test.ts`, `src/plugin-sdk/allowlist-config-edit.ts`); directory-cache invalidation (`src/infra/outbound/target-resolver.ts`); legacy pairing-file migration (`src/infra/state-migrations.channel-pairing.ts`); route indexing (`src/routing/resolve-route.ts`); and audit grouping (`src/security/audit-channel.ts`). None consumes the removed prepared-removal field.

`src/commands/channels/remove.ts:70,73,235` retains `shouldStopRuntime` through `beforeRemoval`, after deletion admission. Count: three declarations/uses.

census: generic accountKey reviewed — 74 callers listed
census: generic shouldStopRuntime reviewed — 3 callers listed

| Symbol | Exact disposition |
| --- | --- |
| S1 `ConfigWriteSnapshot` | Add/remove read receipt; no schema/writer. |
| S2 `PluginCacheScope` | Ancestry retained until scope exit. |
| S3 `ScopedPluginMetadataSnapshot` | Producer metadata/cache plus parent; runtime pinned. |
| S4 `applyChannelAccountRemoval` | Validate callback/no-op before stop/lifecycle. |
| S5 `applyPreparedChannelAccountRemoval` | Removed; callers use applyChannelAccountRemoval. |
| S6 `buildPluginMetadataOwnerMaps` | Enabled owner first, else maintenance owner; no borrowed policy. |
| S7 `clearPluginMetadataLifecycleCaches` | Operation revocation before Gateway guard; process lifetime retained. |
| S8 `createPluginCache` | Existing allocation/cleanup; hosted callbacks live through settlement. |
| S9 `deleteAccountFromConfigSection` | Re-resolve remaining map; propagate refusal. |
| S10 `getCurrentPluginMetadataSnapshot` | Explicit invalidation expires mutable facts; runtime pinned; no fallback. |
| S11 `getScopedPluginCache` | Current-cache projection includes ancestry. |
| S12 `getScopedPluginCaches` | Internal ancestry projection; no new lifetime authority. |
| S13 `invalidatePluginCacheMetadata` | Clear facts; retain modules/instances until cleanup. |
| S14 `prepareChannelAccountConfiguration` | Guard explicit ID; omitted ID reaches plugin defaults. |
| S15 `prepareChannelAccountRemoval` | Removed; applyChannelAccountRemoval owns outcome. |
| S16 `readCommandConfigSnapshot` | Read receipt retained; writer owns callback scope. |
| S17 `registerPluginMetadataProcessMemoLifecycleClear` | Process defaults retained; operation revocation opts in. |
| S18 `requireValidConfigFileSnapshot` | Validation/read/adoption retained; no config key. |
| S19 `requireValidConfigForWrite` | Write receipt retained; policy uses phase scope. |
| S20 `resolveAccountKey` | Existing public selector; optional channel context; explicit policy wins; reject reserved creation. |
| S21 `resolveChannelAccountEntry` | Shared row projection uses selected policy. |
| S22 `resolveChannelAccountKey` | Internal forwarding adapter and delete check; no SDK export. |
| S23 `resolveSignalAccountEntry` | Signal row projection; schema/Doctor/transport retained. |
| S24 `resolveSignalAccountKey` | Signal uses public selector; direct manifest removed. |
| S25 `revokeCurrentPluginMetadataSnapshotScopes` | Single enclosing-cache invalidator; runtime excluded. |
| S26 `runChannelsAddWizardFlow` | Prepared policy through naming/setup/persistence. |
| S27 `runChannelsSetupWizard` | Hosted wizard updates selected stored row. |
| S28 `runCollectedChannelOnboardingPostWriteHooks` | Reread committed config/policy before retained hooks. |
| S29 `runHostedSetup` | One disposable hosted operation through final hook; drops inherited runtime. |
| S30 `runHostedWizard` | Wizard scope through settlement/cancel/postwrite; drops inherited runtime. |
| S31 `runOutsidePluginCache` | Exit clears cache and ancestry. |
| S32 `setupChannels` | Post-install status/config/DM scopes retain callbacks for all callers. |
| S33 `signalAccountKeyPolicy` | Removed; snapshot supplies policy. |
| S34 `withCommandPluginMetadata` | Prepared snapshot/cache carrier returns Promise<Awaited<T>>. |
| S35 `withPluginCache` | Ancestry tracks invalidation, not module retirement. |
| S36 `withPluginMetadataSnapshotScope` | Producer identity detects invalidation; publication preserves facts. |

### Current pinned consumers

All 413 historical typed file rows remain; correction rows below supersede moved references.

| Consumer | Referenced symbols and pinned line numbers; disposition above applies to each |
| --- | --- |
| `extensions/signal/runtime-api.ts` | S9@9 |
| `extensions/signal/src/account-key-repair.ts` | S24@5, 36 |
| `extensions/signal/src/account-selection.ts` | S22@3, 10; S23@13; S24@6, 17 |
| `extensions/signal/src/accounts.ts` | S23@11, 292 |
| `extensions/signal/src/config-compat.ts` | S24@6, 329, 340, 390, 402, 514 |
| `extensions/signal/src/config-schema.ts` | S23@16, 164 |
| `extensions/signal/src/setup-core.ts` | S23@30, 215; S24@30, 365 |
| `extensions/signal/src/setup-transport.ts` | S23@9, 89, 123, 124 |
| `src/agents/agent-bundle-mcp-runtime-config.cache.test.ts` | S7@17, 26; S8@14, 38, 84, 167; S35@15, 39, 84, 103, 159, 167; S36@11, 73, 92 |
| `src/agents/agent-bundle-mcp-runtime-config.test.ts` | S7@3, 32, 58 |
| `src/agents/agent-bundle-mcp-runtime.agent-bundle.test.ts` | S7@10, 25, 156, 217 |
| `src/agents/agent-model-discovery.test.ts` | S7@7, 20 |
| `src/agents/agent-project-settings-snapshot.ts` | S35@12, 87 |
| `src/agents/auth-profile-runtime-contract.test.ts` | S7@15, 95 |
| `src/agents/auth-profiles/order.test.ts` | S7@11, 63 |
| `src/agents/btw.test.ts` | S10@11, 1206 |
| `src/agents/cli-runner/bundle-mcp.test.ts` | S7@11, 147, 190 |
| `src/agents/embedded-agent-runner/compact.delegate-resources.test.ts` | S7@18, 517, 629 |
| `src/agents/embedded-agent-runner/compact.foreground-resources.test.ts` | S7@12, 430 |
| `src/agents/embedded-agent-runner/compact.hooks.harness.ts` | S10@494 |
| `src/agents/embedded-agent-runner/compact.queued-resources.test.ts` | S7@8, 214 |
| `src/agents/embedded-agent-runner/compaction-session-execution.ts` | S10@21, 187 |
| `src/agents/embedded-agent-runner/history.ts` | S21@10, 192 |
| `src/agents/embedded-agent-runner/model.configured-pricing.test.ts` | S36@7, 67 |
| `src/agents/embedded-agent-runner/model.generation-scope.test-support.ts` | S7@7, 161 |
| `src/agents/embedded-agent-runner/model.generation-scope.test.ts` | S7@6, 101 |
| `src/agents/embedded-agent-runner/model.manifest-alias.ts` | S10@7, 304 |
| `src/agents/embedded-agent-runner/model.provider-hooks.ts` | S10@7, 51 |
| `src/agents/embedded-agent-runner/model.static-catalog.provider-alias.test.ts` | S7@18, 94 |
| `src/agents/embedded-agent-runner/model.static-catalog.snapshot-cache.test.ts` | S7@3, 123, 339 |
| `src/agents/embedded-agent-runner/model.static-catalog.test.ts` | S7@58, 131; S8@57, 169; S35@57, 169 |
| `src/agents/embedded-agent-runner/model.static-catalog.ts` | S10@10, 122 |
| `src/agents/embedded-agent-runner/run-orchestrator.cleanup-resources.test.ts` | S7@8, 317 |
| `src/agents/embedded-agent-runner/run/runtime-preparation.thinking.test.ts` | S7@9, 152 |
| `src/agents/exec-auto-reviewer.resources.test.ts` | S7@9, 265 |
| `src/agents/identity.ts` | S21@8, 33, 117 |
| `src/agents/isolated-completion.resources.test.ts` | S7@10, 333 |
| `src/agents/mcp-auth-profile.integration.test-support.ts` | S8@501; S35@501 |
| `src/agents/model-catalog.ts` | S10@11, 191 |
| `src/agents/model-discovery-context.ts` | S10@8, 50 |
| `src/agents/model-fallback-candidates.generation.test.ts` | S8@8, 51; S35@8, 51; S36@6, 251, 264 |
| `src/agents/model-fallback-candidates.ts` | S10@11, 188, 193 |
| `src/agents/model-fast-mode.ts` | S35@3, 21 |
| `src/agents/model-ref-shared.test.ts` | S7@10, 26, 31 |
| `src/agents/model-selection-shared.ts` | S10@17, 115, 192, 1297 |
| `src/agents/model-suppression.test.ts` | S7@21, 33; S8@19, 49, 50; S10@17, 161; S35@19, 59, 60, 61 |
| `src/agents/models-config.providers.normalize-keys.test.ts` | S36@10, 257 |
| `src/agents/models-config.write-serialization.test.ts` | S7@61, 163 |
| `src/agents/openclaw-tools.media-factory-plan.test.ts` | S7@9, 191, 203; S10@5, 374, 376 |
| `src/agents/prepared-model-catalog-worker.metadata.integration.test.ts` | S8@4, 22; S10@53; S35@7, 23, 59 |
| `src/agents/prepared-model-catalog.resources.test.ts` | S7@11, 106, 183 |
| `src/agents/prepared-model-runtime-lease.ts` | S36@3, 169 |
| `src/agents/prepared-model-runtime.inbound-registry.ts` | S10@6, 77 |
| `src/agents/prepared-model-runtime.plugin-context.test.ts` | S7@7, 21 |
| `src/agents/prepared-model-runtime.published-resources.test.ts` | S7@12, 207, 325 |
| `src/agents/prepared-model-runtime.run-resources.test.ts` | S7@14, 215, 251 |
| `src/agents/provider-attribution.test.ts` | S7@174, 217; S8@173, 312; S35@173, 311 |
| `src/agents/provider-auth-aliases.test.ts` | S7@67, 260, 619; S8@66, 505, 506; S35@66, 524, 527 |
| `src/agents/provider-auth-aliases.ts` | S10@10, 59, 65 |
| `src/agents/runtime-plan/auth.test.ts` | S7@43, 62 |
| `src/agents/runtime-plan/prepare-auth.metadata.test.ts` | S36@3, 29, 94, 110 |
| `src/agents/runtime-plugins.context-engine.integration.test.ts` | S8@14, 345, 346; S35@14, 347, 348 |
| `src/agents/runtime-plugins.hooks.integration.test.ts` | S8@14, 47, 48; S35@14, 50, 53 |
| `src/agents/runtime-plugins.ts` | S36@8, 167, 217 |
| `src/agents/sandbox/sanitize-env-vars.ts` | S10@7, 118 |
| `src/agents/simple-completion-runtime.plugin-scope.test.ts` | S7@9, 97 |
| `src/agents/simple-completion-runtime.selected-model.test.ts` | S7@9, 20 |
| `src/agents/simple-completion-runtime.test.ts` | S10@35 |
| `src/agents/subagents/spawn/acp-spawn-parent-stream.ts` | S21@25, 124 |
| `src/agents/tool-policy-declared-context.ts` | S10@6, 130 |
| `src/agents/tools-effective-inventory.cold-provider.test.ts` | S7@26, 120, 134 |
| `src/agents/tools/manifest-capability-availability.ts` | S10@8, 157 |
| `src/agents/tools/media-generate-tool.donor-resources.test.ts` | S7@7, 43 |
| `src/agents/tools/media-generate-tool.resources.test.ts` | S7@16, 289 |
| `src/agents/tools/pdf-tool.helpers.test.ts` | S36@5, 105 |
| `src/agents/tools/video-generate-tool.test.ts` | S7@18, 373; S10@11, 492 |
| `src/agents/utility-model.ts` | S10@5, 50 |
| `src/auto-reply/chunk.ts` | S21@9, 49, 92 |
| `src/auto-reply/command-auth.ts` | S21@16, 454, 475 |
| `src/auto-reply/reply/block-streaming.ts` | S21@6, 60 |
| `src/auto-reply/reply/commands-account-policy.test.ts` | S36@4, 82 |
| `src/auto-reply/reply/get-reply-directive-aliases.test.ts` | S36@12, 162 |
| `src/auto-reply/reply/get-reply-run.prepared-metadata.test.ts` | S10@3, 75, 84, 122 |
| `src/auto-reply/reply/memory-flush.test.ts` | S36@13, 286 |
| `src/auto-reply/reply/model-runtime-normalization.ts` | S10@12, 25 |
| `src/auto-reply/reply/reply-threading.ts` | S21@11, 51 |
| `src/auto-reply/reply/stage-sandbox-media.scp.test.ts` | S7@11, 178 |
| `src/channels/account-config-enabled.ts` | S21@3, 13 |
| `src/channels/bundled-channel-catalog-read.test.ts` | S7@48, 362, 383 |
| `src/channels/draft-streaming-chunking.ts` | S21@4, 33 |
| `src/channels/join-intro/report-channel-room-join.ts` | S21@13, 74 |
| `src/channels/plugins/account-config-mutation.test.ts` | S4@6, 297, 333, 371, 402, 428; S14@7, 28, 100, 148, 180, 202, 241 |
| `src/channels/plugins/account-config-mutation.ts` | S4@200; S14@67; S22@5, 97 |
| `src/channels/plugins/account-key-policy.test.ts` | S36@11, 75 |
| `src/channels/plugins/bundled.shape-guard.test.ts` | S7@8, 223 |
| `src/channels/plugins/catalog.test.ts` | S7@8, 30, 81, 115, 236, 253; S8@7, 76, 107; S35@7, 76, 106 |
| `src/channels/plugins/config-helpers.test.ts` | S9@7, 49 |
| `src/channels/plugins/config-helpers.ts` | S9@115; S20@8, 197; S22@9, 87, 125, 143, 190 |
| `src/channels/plugins/config-write-policy-shared.ts` | S21@6, 71 |
| `src/channels/plugins/helpers.ts` | S22@9, 57, 63 |
| `src/channels/plugins/read-only.legacy-workspace.test.ts` | S7@4, 22 |
| `src/channels/plugins/read-only.test.ts` | S7@18, 847, 884 |
| `src/channels/plugins/setup-contract.test.ts` | S8@3, 27; S35@3, 27 |
| `src/channels/plugins/setup-helpers.ts` | S22@8, 50, 93, 311, 370 |
| `src/cli/capability-cli/model.resources.test.ts` | S7@12, 279 |
| `src/cli/channel-auth.ts` | S19@13, 108 |
| `src/cli/command-config-snapshot.ts` | S16@7 |
| `src/cli/directory-cli.ts` | S19@19, 114 |
| `src/cli/node-worker-bootstrap.test.ts` | S7@30, 51 |
| `src/cli/plugins-cli.policy.test.ts` | S7@8, 66, 93 |
| `src/cli/plugins-feature-artifact.test.ts` | S8@14, 138, 294; S35@14, 138, 294 |
| `src/cli/plugins-feature-artifact.ts` | S8@17, 66; S35@17, 66 |
| `src/cli/plugins-update-command.ts` | S8@48, 544; S35@48, 544 |
| `src/cli/program/config-guard.test.ts` | S8@11, 94, 152; S35@13, 153 |
| `src/cli/run-main.exit.test.ts` | S11@17, 668, 672 |
| `src/cli/run-main.ts` | S8@22, 1017; S35@22, 1017 |
| `src/cli/update-cli/update-command-plugins.degradation.test.ts` | S8@11, 225; S35@11, 225 |
| `src/commands/agents.add.test.ts` | S32@23 |
| `src/commands/agents.commands.add.ts` | S19@51, 123; S32@56, 443 |
| `src/commands/agents.commands.bind.ts` | S19@14, 122 |
| `src/commands/agents.commands.delete.ts` | S19@67, 138 |
| `src/commands/agents.commands.identity.ts` | S19@30, 70 |
| `src/commands/channel-setup/plugin-install.test.ts` | S7@99, 215, 231 |
| `src/commands/channels.add.test.ts` | S8@18, 843; S21@22, 804; S27@43, 490; S32@142; S35@18, 844 |
| `src/commands/channels.remove.test.ts` | S8@10, 613; S9@5, 334, 604; S35@10, 613 |
| `src/commands/channels/add-wizard.ts` | S26@125, 340; S27@317; S32@142; S34@24, 205 |
| `src/commands/channels/add.ts` | S1@29, 145; S14@7, 288; S19@32, 137; S26@156; S28@343; S34@29, 274 |
| `src/commands/channels/capabilities.ts` | S18@32, 287; S19@33, 284 |
| `src/commands/channels/remove.ts` | S4@4, 224; S1@21, 116; S19@25, 102; S34@21, 106 |
| `src/commands/channels/shared.ts` | S19@11, 18 |
| `src/commands/config-validation.test.ts` | S19@4, 63, 86 |
| `src/commands/config-validation.ts` | S1@54; S16@39; S18@27, 119; S19@46; S34@57; S36@63 |
| `src/commands/configure.wizard.default-agent.test.ts` | S32@8 |
| `src/commands/configure.wizard.ts` | S32@55, 707 |
| `src/commands/doctor-config-preflight-plugin-index.ts` | S8@9, 70; S35@9, 71 |
| `src/commands/doctor-config-preflight-plugin-verification.test.ts` | S8@10, 88, 105, 112, 190, 193; S35@10, 88, 105, 112, 190, 193 |
| `src/commands/doctor-config-preflight.plugin-persistence.test.ts` | S8@19, 169, 207, 214, 225, 262, 273, 354, 370, 427, 463, 478, 500, 529, 553, 596; S10@12, 237, 302, 308, 317, 324; S35@22, 169, 207, 214, 226, 262, 273, 354, 370, 427, 463, 479, 500, 529, 553, 596; S36@13, 502 |
| `src/commands/doctor-maintenance.plugin-preflight.test.ts` | S7@11, 20, 120 |
| `src/commands/doctor-plugin-registry-generation-repair.test.ts` | S8@20, 89, 91; S35@20, 89, 91 |
| `src/commands/doctor-post-upgrade.test.ts` | S7@11, 22 |
| `src/commands/doctor/channel-capabilities.packaged.test.ts` | S7@34, 43, 50 |
| `src/commands/doctor/shared/channel-plugin-blockers.test.ts` | S7@7, 59 |
| `src/commands/doctor/shared/legacy-config-account-promotion.test.ts` | S7@6, 19, 98, 162, 254 |
| `src/commands/doctor/shared/legacy-config-binding-repair.ts` | S21@7, 99 |
| `src/commands/doctor/shared/legacy-config-issues.ts` | S36@10, 74 |
| `src/commands/doctor/shared/missing-configured-plugin-install.load-path.test.ts` | S7@12, 22 |
| `src/commands/doctor/shared/plugin-metadata-snapshot-scope.ts` | S8@8, 78, 88, 153; S35@10, 136; S36@4, 138 |
| `src/commands/doctor/shared/post-core-plugin-convergence.source-checkout.test.ts` | S8@20, 246, 257, 329; S35@20, 246, 257, 329 |
| `src/commands/doctor/shared/stale-auth-order.test.ts` | S7@17, 123 |
| `src/commands/doctor/shared/xai-auto-retirement.test.ts` | S7@5, 19, 28 |
| `src/commands/migrate.resources.test.ts` | S7@8, 22 |
| `src/commands/models/auth.registry.test.ts` | S7@5, 24 |
| `src/commands/models/list.manifest-catalog.snapshot.test.ts` | S7@6, 22 |
| `src/commands/models/list.probe.resources.test.ts` | S7@17, 331 |
| `src/commands/models/list.status-command.ts` | S36@75, 350 |
| `src/commands/models/list.status.test.ts` | S7@8, 681, 700, 719; S10@6, 680, 683, 698, 710 |
| `src/commands/models/model-selection.runtime.test.ts` | S7@18, 74 |
| `src/commands/onboard-channels.e2e.test.ts` | S32@98, 604 |
| `src/commands/onboard-channels.ts` | S28@5; S32@6 |
| `src/commands/onboard-quickstart-host.plugin-generation.test.ts` | S7@10, 15, 79; S8@8, 28, 82; S35@8, 28, 82 |
| `src/commands/onboard-quickstart-host.ts` | S8@7, 27; S35@7, 27 |
| `src/commands/onboarding-plugin-install.ts` | S7@66, 131 |
| `src/commands/plugin-control-plane-cold-imports.test.ts` | S7@3, 28 |
| `src/commands/status-all/channels-manifest-discovery.test.ts` | S8@8, 69; S35@8, 69 |
| `src/commands/status.plugin-metadata-snapshot.test.ts` | S7@3, 48, 73 |
| `src/commands/status.scan-overview.ts` | S16@159 |
| `src/config/channel-account-config.ts` | S20@3, 83; S22@4, 76 |
| `src/config/channel-capabilities.ts` | S21@4, 51 |
| `src/config/channel-doctor-helpers.ts` | S22@3, 196 |
| `src/config/context-visibility.ts` | S21@2, 54 |
| `src/config/group-policy.ts` | S21@3, 104; S22@3, 75 |
| `src/config/implicit-mentions.ts` | S21@2, 29 |
| `src/config/io.context.plugin-metadata.test.ts` | S7@8, 133 |
| `src/config/io.plugin-metadata.ts` | S8@8, 88; S35@8, 88 |
| `src/config/io.snapshot.recovery.test.ts` | S7@7, 18 |
| `src/config/io.snapshot.test.ts` | S7@8, 26 |
| `src/config/io.snapshot.ts` | S36@4, 256 |
| `src/config/markdown-tables.ts` | S21@5, 57 |
| `src/config/plugin-auto-enable.apply.ts` | S17@5, 32 |
| `src/config/plugin-auto-enable.channels.test.ts` | S7@6, 167, 264 |
| `src/config/plugin-auto-enable.core.test.ts` | S7@8, 1247, 1342, 1372, 1407, 1441 |
| `src/config/plugin-auto-enable.shared.ts` | S10@10, 658, 669 |
| `src/config/plugin-auto-enable.test-helpers.ts` | S7@5, 16 |
| `src/config/test-helpers.ts` | S7@6, 12 |
| `src/config/validation.channel-metadata.test.ts` | S7@6, 273 |
| `src/config/validation.dm-policy.test.ts` | S7@3, 15 |
| `src/context-engine/registry.copied-view-resources.test.ts` | S7@16, 37 |
| `src/cron/delivery-channel-validation.ts` | S21@9, 99 |
| `src/cron/trigger-script.preparation.test.ts` | S7@21, 105 |
| `src/flows/channel-setup.test.ts` | S8@5, 1629; S32@224, 230, 236, 243, 248, 250, 899, 1298, 1335, 1819; S35@5, 1630 |
| `src/flows/channel-setup.ts` | S28@77, 90; S32@156; S34@27, 106, 289, 439, 449, 582, 986, 1088, 1105; S35@38, 251, 727 |
| `src/gateway/config-reload.test.ts` | S8@55, 6782, 6819; S35@55, 6782, 6819 |
| `src/gateway/config-reload.ts` | S8@44, 376; S35@44, 376 |
| `src/gateway/control-ui-plugin-assets.ts` | S8@15, 163; S35@15, 163 |
| `src/gateway/health/collector.channel-discovery.test.ts` | S7@12, 30 |
| `src/gateway/http-utils.ts` | S10@18, 181 |
| `src/gateway/server-channels.ts` | S21@64, 374, 382 |
| `src/gateway/server-close.metadata.test-support.ts` | S35@7, 107 |
| `src/gateway/server-close.model-cache.test.ts` | S10@13, 297; S36@14, 204 |
| `src/gateway/server-http-plugin-auth.test.ts` | S7@4, 18, 41, 72 |
| `src/gateway/server-http-plugin-auth.ts` | S17@3, 28 |
| `src/gateway/server-methods/migrations.resources.test.ts` | S7@11, 19 |
| `src/gateway/server-methods/wizard.test.ts` | S8@10, 148; S10@7, 164, 173, 192 |
| `src/gateway/server-methods/wizard.ts` | S8@15, 62; S27@57; S30@61, 120, 135; S35@15, 65 |
| `src/gateway/server-plugin-bootstrap.ts` | S35@8, 61 |
| `src/gateway/server-plugin-reload.cache.test-support.ts` | S8@8, 40, 119; S35@10, 41, 63, 120, 185 |
| `src/gateway/server-plugin-reload.installed-package.test.ts` | S7@16, 55 |
| `src/gateway/server-plugin-reload.recovery.test.ts` | S7@8, 118 |
| `src/gateway/server-plugin-reload.ts` | S8@21, 97; S35@21, 270, 286, 297 |
| `src/gateway/server-plugins.lifecycle.test.ts` | S7@11, 313 |
| `src/gateway/server-plugins.ts` | S10@9, 290 |
| `src/gateway/server-startup-lifetime.test.ts` | S8@29, 178, 203; S35@31, 206 |
| `src/gateway/server-startup-minimal-boot.test.ts` | S7@12, 29 |
| `src/gateway/server-startup-plugin-quarantine.test.ts` | S8@26, 407, 438; S35@26, 407, 438 |
| `src/gateway/server-startup-workspace-readiness.test.ts` | S7@14, 55 |
| `src/gateway/server.chat.gateway-server-chat-b.test.ts` | S36@47, 2071 |
| `src/gateway/server.config-patch.test.ts` | S7@13, 160 |
| `src/gateway/server.config-policy-response.test.ts` | S7@7, 44 |
| `src/gateway/server.config-security-policy.test.ts` | S7@5, 44 |
| `src/gateway/server.sessions.create.test.ts` | S10@612; S36@612 |
| `src/gateway/server.shared-auth-rotation.test.ts` | S7@20, 71 |
| `src/gateway/session-utils.test.ts` | S7@29, 328 |
| `src/gateway/sessions-patch.test.ts` | S7@9, 317 |
| `src/image-generation/runtime.resources.test.ts` | S7@14, 153 |
| `src/infra/dotenv-workspace-blocklist.test.ts` | S7@12, 134 |
| `src/infra/event-session-routing.ts` | S21@6, 113 |
| `src/infra/heartbeat-visibility.ts` | S21@4, 54 |
| `src/infra/state-migrations.caller-mode.inventory.test.ts` | S8@16, 100, 112, 118, 156; S35@16, 100, 112, 118, 156; S36@6, 120 |
| `src/infra/update-candidate-bundled-provenance.test.ts` | S8@10, 167, 263, 385; S35@10, 167, 263, 385 |
| `src/media-understanding/defaults.generation.test.ts` | S36@3, 60, 64 |
| `src/media/channel-inbound-roots.installed-plugin.test.ts` | S7@10, 22, 183 |
| `src/media/channel-inbound-roots.lifecycle.test.ts` | S8@5, 22, 23; S35@5, 50 |
| `src/media/configured-max-bytes.ts` | S21@6, 39 |
| `src/media/document-extractors.runtime.test.ts` | S7@8, 121 |
| `src/music-generation/runtime.resources.test.ts` | S7@14, 147 |
| `src/plugin-sdk/account-resolution.ts` | S20@21; S22@22 |
| `src/plugin-sdk/allowlist-config-edit.ts` | S22@8, 197 |
| `src/plugin-sdk/channel-config-helpers.ts` | S9@11, 292, 468 |
| `src/plugin-sdk/channel-entry-contract.lifecycle.test.ts` | S8@6, 37; S35@6, 50, 83 |
| `src/plugin-sdk/channel-plugin-common.ts` | S9@20 |
| `src/plugin-sdk/core.ts` | S9@249 |
| `src/plugin-sdk/facade-loader.test.ts` | S7@9, 505 |
| `src/plugin-sdk/facade-runtime.test.ts` | S7@13, 104, 164, 351, 377 |
| `src/plugins/activation-context.test.ts` | S7@10, 36 |
| `src/plugins/activation-context.ts` | S10@11, 100, 108 |
| `src/plugins/bundled-capability-runtime.test.ts` | S8@14, 130; S35@14, 130 |
| `src/plugins/bundled-dir.test.ts` | S8@10, 383, 416, 428, 448, 497; S35@10, 383, 417, 423, 425, 428, 431, 448, 497 |
| `src/plugins/bundled-discovery-state.ts` | S17@9, 42 |
| `src/plugins/bundled-package-channel-metadata.test.ts` | S7@16, 34, 126 |
| `src/plugins/bundled-plugin-metadata.public-surfaces.test.ts` | S7@11, 16 |
| `src/plugins/bundled-plugin-metadata.test.ts` | S7@29, 39, 826 |
| `src/plugins/capability-artifact.ts` | S8@18, 135; S35@18, 135 |
| `src/plugins/capability-consent.ts` | S17@40, 81 |
| `src/plugins/capability-provider-runtime.test.ts` | S7@164, 398 |
| `src/plugins/capability-provider-runtime.ts` | S10@14, 196 |
| `src/plugins/channel-catalog-registry.workspace.test.ts` | S7@13, 19, 61, 137; S8@12, 109; S35@12, 109 |
| `src/plugins/cli-config-lifetime.test.ts` | S7@24, 143; S10@16, 146, 220 |
| `src/plugins/cli-metadata-lifetime.test.ts` | S7@31, 61, 90; S10@21, 276, 320, 399, 464 |
| `src/plugins/cli-registry-loader.ts` | S8@24, 78; S35@24, 84 |
| `src/plugins/current-plugin-metadata-snapshot.test.ts` | S7@29, 825, 851, 872; S8@26, 840, 841; S10@12, 130, 133, 135, 141, 163, 169, 179, 185, 211, 214, 218, 230, 281, 306, 325, 346, 350, 356, 374, 385, 413, 424, 443, 465, 480, 500, 502, 506, 518, 530, 532, 545, 553, 588, 595, 627, 633, 636, 654, 656, 667, 672, 673, 674, 675, 686, 691, 708, 709, 713, 714, 731, 733, 735, 737, 745, 749, 757, 761, 773, 777, 789, 790, 807, 810, 818, 827, 852, 854, 856, 858, 861, 873, 883, 892, 895, 912, 914, 919, 979; S36@17, 158, 342, 370, 381, 405, 409, 439, 462, 552, 710, 848, 849, 855, 909 |
| `src/plugins/current-plugin-metadata-snapshot.ts` | S10@393, 444; S11@17, 188, 218, 410; S12@14, 198; S13@15, 209; S17@27, 447; S25@197, 447; S31@18, 283; S3@66, 70, 83, 214; S35@19, 163, 263; S36@223 |
| `src/plugins/discovery-checkout.test.ts` | S8@8, 47, 113, 184; S35@8, 47, 113, 184 |
| `src/plugins/discovery.test.ts` | S7@20, 473, 3309; S8@19, 3346, 3370, 3391; S35@19, 3346, 3370, 3391 |
| `src/plugins/doctor-contract-registry.test-fixtures.ts` | S7@3, 7 |
| `src/plugins/doctor-contract-registry.test.ts` | S8@8, 125, 134, 138; S35@8, 132, 134, 136, 138 |
| `src/plugins/host-hook-cleanup.retirement.test.ts` | S8@9, 125 |
| `src/plugins/install-persistence.enablement.test.ts` | S7@19, 69 |
| `src/plugins/install-persistence.test.ts` | S7@23, 49 |
| `src/plugins/install-persistence.ts` | S8@36, 218; S35@36, 218 |
| `src/plugins/install.archive-dependencies.test.ts` | S8@7, 77; S35@7, 77 |
| `src/plugins/installed-plugin-index-facts.test.ts` | S8@8, 49, 103, 115, 145, 152; S35@8, 49, 103, 115, 151, 152, 153, 156 |
| `src/plugins/installed-plugin-index-store-write.ts` | S7@56, 237 |
| `src/plugins/installed-plugin-index-store.test.ts` | S7@40, 48; S10@17, 270, 286 |
| `src/plugins/installed-plugin-index.compat.test.ts` | S7@16, 23 |
| `src/plugins/installed-plugin-index.test.ts` | S8@24, 427, 1079, 1127; S35@24, 427, 1079, 1127 |
| `src/plugins/legacy-session-surfaces.state-migration.test.ts` | S7@11, 20, 171, 267, 345 |
| `src/plugins/loader-load-context.ts` | S10@15, 327, 333 |
| `src/plugins/loader-module-runtime.ts` | S35@5, 144, 160, 228, 241 |
| `src/plugins/loader-runtime-load.ts` | S8@16, 113; S35@16, 147 |
| `src/plugins/loader.capability-factory.test.ts` | S8@28, 183, 184, 479; S35@31, 194, 196, 481 |
| `src/plugins/loader.hooks-and-runtime.test-utils.ts` | S8@31, 236; S35@31, 239 |
| `src/plugins/loader.instance-cleanup.test.ts` | S8@15, 122, 185, 234, 376, 422, 476, 501; S35@15, 130, 135, 137, 186, 379, 426, 482, 504 |
| `src/plugins/loader.lazy-alias.test.ts` | S8@18, 128, 567, 570, 606, 609, 626, 634; S35@18, 128, 567, 570, 608, 610, 611, 615, 618, 623, 626, 646 |
| `src/plugins/loader.runtime-registry.test.ts` | S7@49, 848 |
| `src/plugins/management-catalog.ts` | S11@36, 48; S35@37, 63 |
| `src/plugins/management-service.capability-consent.test.ts` | S7@20, 165 |
| `src/plugins/management-service.inspect.test.ts` | S7@8, 28 |
| `src/plugins/management-service.lifecycle-cache.test.ts` | S7@6, 126, 173, 339, 505; S17@7, 47 |
| `src/plugins/management-service.policy-imports.test.ts` | S7@26, 44 |
| `src/plugins/management-service.registry-refresh.test.ts` | S7@5, 179 |
| `src/plugins/management-service.ts` | S8@65, 184; S35@65, 185 |
| `src/plugins/management-service.workspace-inventory.test.ts` | S7@19, 52 |
| `src/plugins/manifest-backup-resources.test.ts` | S7@8, 58 |
| `src/plugins/manifest-contract-eligibility.test.ts` | S7@41, 56; S17@12 |
| `src/plugins/manifest-metadata-scan.test.ts` | S7@13, 88, 184, 206 |
| `src/plugins/manifest-model-id-normalization.test.ts` | S7@13, 99, 105, 158, 167; S36@9, 123 |
| `src/plugins/manifest-model-suppression.test.ts` | S8@20, 67, 68; S35@20, 82, 83, 90 |
| `src/plugins/manifest-registry-installed.ownership.test.ts` | S7@19, 25, 93 |
| `src/plugins/manifest-registry-installed.test.ts` | S7@15, 21, 318; S8@14, 284; S35@14, 284 |
| `src/plugins/manifest-registry.test.ts` | S8@13, 523; S35@13, 523 |
| `src/plugins/manifest.json5-tolerance.test.ts` | S7@8, 18 |
| `src/plugins/memory-runtime.test.ts` | S8@14, 270, 345 |
| `src/plugins/migration-provider-runtime.test.ts` | S7@13, 183 |
| `src/plugins/plugin-cache-primitives.test.ts` | S7@7, 94, 130 |
| `src/plugins/plugin-cache-primitives.ts` | S17@3, 57 |
| `src/plugins/plugin-cache.test.ts` | S7@24, 31, 50; S8@17, 39, 78, 174, 210, 223; S35@20, 43, 78, 174, 212, 225 |
| `src/plugins/plugin-cache.ts` | S8@165, 185; S11@194, 208; S12@199; S13@146; S2@48, 52, 59; S31@215; S35@211 |
| `src/plugins/plugin-discovery-ordering.test.ts` | S7@8, 70 |
| `src/plugins/plugin-generation-conditions.test.ts` | S8@6, 23; S35@6, 23 |
| `src/plugins/plugin-lifecycle-lease.ts` | S8@12, 126; S35@15, 131 |
| `src/plugins/plugin-metadata-account-key-policies.test.ts` | S7@5, 16; S8@4, 51; S35@4, 51 |
| `src/plugins/plugin-metadata-lifecycle.test.ts` | S7@18, 92, 115, 128, 209; S8@10, 145, 234; S17@19, 25; S35@14, 145, 235 |
| `src/plugins/plugin-metadata-lifecycle.ts` | S7@244; S17@236; S35@19, 143 |
| `src/plugins/plugin-metadata-readers.runtime.ts` | S10@2 |
| `src/plugins/plugin-metadata-snapshot-readers.ts` | S10@15 |
| `src/plugins/plugin-metadata-snapshot-required.ts` | S10@34, 35, 38 |
| `src/plugins/plugin-metadata-snapshot.runtime.ts` | S10@54, 55, 58 |
| `src/plugins/plugin-metadata-snapshot.test.ts` | S7@37, 134; S8@32, 148, 228, 240; S10@18, 241, 246; S35@35, 149, 230, 240; S36@20, 163, 237, 264, 835 |
| `src/plugins/plugin-metadata-snapshot.ts` | S6@195, 283; S8@29, 381; S10@10, 388, 535; S35@32, 381, 481 |
| `src/plugins/plugin-module-generation.bun.test-support.ts` | S8@5, 46; S35@5, 46 |
| `src/plugins/plugin-module-generation.interop.test.ts` | S8@8, 38; S35@8, 38 |
| `src/plugins/plugin-module-generation.sdk.test.ts` | S8@7, 25, 58; S35@9, 25 |
| `src/plugins/plugin-module-generation.test.ts` | S8@8, 26; S35@8, 26 |
| `src/plugins/plugin-module-loader-cache.test.ts` | S8@11, 24, 25, 30, 214, 215; S35@14, 34, 225, 235 |
| `src/plugins/plugin-module-loader-cache.ts` | S35@24, 211, 450, 609 |
| `src/plugins/plugin-native-module-loader.ts` | S35@9, 56, 86, 129 |
| `src/plugins/plugin-registry-contributions.current-snapshot.test.ts` | S7@13, 27, 289 |
| `src/plugins/plugin-registry-inspection.test.ts` | S7@13, 26, 31, 148, 424 |
| `src/plugins/plugin-registry-snapshot.state-migration.test.ts` | S7@25, 41, 46, 133, 255; S8@24, 256; S35@24, 256 |
| `src/plugins/plugin-registry-snapshot.test.ts` | S7@18, 30, 1462 |
| `src/plugins/plugin-registry-snapshot.ts` | S8@49, 574; S10@14, 131; S35@49, 574 |
| `src/plugins/plugin-registry.test.ts` | S7@18, 36, 60, 951 |
| `src/plugins/plugin-sdk-native-resolver.test.ts` | S7@9, 255 |
| `src/plugins/prepared-model-generation.lifecycle.test.ts` | S36@9, 137 |
| `src/plugins/provider-auth-choice.install-discovery.test.ts` | S10@12, 258; S11@17, 202 |
| `src/plugins/provider-auth-choice.ts` | S8@18, 377, 378; S35@18, 394, 451, 516, 536 |
| `src/plugins/provider-auth-choices.test.ts` | S7@57 |
| `src/plugins/provider-discovery.runtime.ts` | S35@9, 263 |
| `src/plugins/provider-external-auth-core.ts` | S10@2, 23 |
| `src/plugins/provider-model-routes.installed.test.ts` | S36@14, 60, 183, 232, 288 |
| `src/plugins/provider-public-artifacts.test.ts` | S7@13, 78, 908; S8@10, 398, 399, 899, 911; S35@10, 400, 411, 430, 438, 904, 910, 911 |
| `src/plugins/provider-runtime.ts` | S10@22, 763 |
| `src/plugins/provider-setup-availability.ts` | S8@7, 36; S35@7, 39, 73 |
| `src/plugins/provider-thinking.ts` | S10@4, 63; S35@5, 27 |
| `src/plugins/providers.runtime-core.ts` | S10@15, 187, 199 |
| `src/plugins/providers.runtime.consult-current-snapshot.test.ts` | S7@12, 95, 102 |
| `src/plugins/providers.ts` | S10@6, 424, 564 |
| `src/plugins/public-surface-generation.test.ts` | S8@18, 87; S35@18, 97 |
| `src/plugins/public-surface-loader.test.ts` | S7@378, 421, 557 |
| `src/plugins/registry-refresh.ts` | S8@8, 34; S35@8, 34 |
| `src/plugins/runtime-context.test.ts` | S8@3, 25, 45; S35@3, 25, 45 |
| `src/plugins/runtime-plugin-boundary.whatsapp.test.ts` | S7@8, 156 |
| `src/plugins/runtime.ts` | S7@28, 690 |
| `src/plugins/runtime/generation-scope.ts` | S36@3, 28 |
| `src/plugins/runtime/load-context.current-snapshot.test.ts` | S7@9, 74; S10@4, 104, 110 |
| `src/plugins/runtime/load-context.test.ts` | S7@72, 100; S8@5, 260, 263; S35@5, 260, 263 |
| `src/plugins/runtime/runtime-llm.prepared-owner.test.ts` | S7@40, 956 |
| `src/plugins/runtime/runtime-web-channel-plugin.test.ts` | S8@15, 102; S35@15, 112 |
| `src/plugins/sdk-alias.test.ts` | S8@13, 1755, 1756; S35@13, 1763, 1767 |
| `src/plugins/sdk-alias.ts` | S35@27, 1400, 1410, 1436 |
| `src/plugins/setup-registry.lifecycle.test.ts` | S7@30, 64, 517, 587; S8@21, 90, 127, 176, 232, 614, 630, 684, 685, 758; S11@23, 321, 343, 984, 986; S35@25, 92, 129, 178, 234, 239, 621, 629, 647, 660, 682, 683, 702, 714, 719, 736, 759, 766, 768, 771, 806; S36@13, 432 |
| `src/plugins/setup-registry.runtime.test.ts` | S7@7, 48; S10@34, 38; S36@3, 92, 123, 151, 167 |
| `src/plugins/setup-registry.test-fixtures.ts` | S7@2, 5 |
| `src/plugins/setup-registry.test.ts` | S7@1301; S8@8, 1223, 1224; S35@8, 1234 |
| `src/plugins/setup-registry.ts` | S35@28, 537 |
| `src/plugins/status-effective-plugin-discovery.test.ts` | S7@8, 97, 104, 114, 130, 133, 141 |
| `src/plugins/status.registry-snapshot.bundles.test.ts` | S7@4, 20 |
| `src/plugins/status.registry-snapshot.dependency-health.test.ts` | S7@6, 18 |
| `src/plugins/status.registry-snapshot.test.ts` | S7@13, 59; S10@8, 551, 603 |
| `src/plugins/status.runtime-inspection.test.ts` | S7@36, 51 |
| `src/plugins/status.test.ts` | S7@6, 354 |
| `src/plugins/status.ts` | S8@31, 395; S35@31, 396 |
| `src/plugins/tools.optional.test.ts` | S7@114, 622; S8@23, 3080, 3767 |
| `src/plugins/update-cohort.integration.test.ts` | S8@8, 100; S35@8, 100 |
| `src/plugins/update-cohort.test.ts` | S8@9, 230; S35@9, 230 |
| `src/plugins/update-cohort.ts` | S8@12, 74, 153; S35@12, 74, 153 |
| `src/plugins/web-provider-resolution-shared.ts` | S10@3, 147 |
| `src/routing/account-lookup.test.ts` | S20@6, 16 |
| `src/routing/account-lookup.ts` | S20@51, 77, 89, 94; S21@54; S22@19, 27, 35, 61 |
| `src/secrets/provider-env-vars.ts` | S10@7, 138, 145, 158 |
| `src/secrets/resolve.ts` | S10@16, 166 |
| `src/security/dangerous-config-flags-current-snapshot.test.ts` | S10@5, 31, 36, 50 |
| `src/security/dangerous-config-flags-current.ts` | S10@4, 21 |
| `src/skills/loading/plugin-skills.test.ts` | S7@17, 197; S8@16, 271; S35@16, 271 |
| `src/skills/loading/plugin-skills.ts` | S17@17, 39; S35@16, 70 |
| `src/skills/loading/skills.test.ts` | S7@10, 183, 346 |
| `src/system-agent/approval-intent.resources.test.ts` | S7@15, 333 |
| `src/system-agent/config-redaction.test.ts` | S36@7, 204 |
| `src/system-agent/config-redaction.ts` | S10@27, 137, 146 |
| `src/system-agent/hosted-setup.runtime.test.ts` | S8@8, 690; S10@5, 707, 728, 776 |
| `src/system-agent/hosted-setup.runtime.ts` | S8@3, 62; S29@49, 99, 138, 160, 202; S32@96; S35@3, 64 |
| `src/system-agent/plugin-artifact.ts` | S8@13, 169; S35@13, 169 |
| `src/system-agent/setup-inference-activate.ts` | S8@31, 453 |
| `src/system-agent/setup-inference-credentials.lifecycle.test.ts` | S7@10, 17 |
| `src/system-agent/setup-inference-credentials.ts` | S8@20, 77; S35@20, 82, 121 |
| `src/system-agent/setup-inference-detect.lifecycle.test.ts` | S7@7, 14 |
| `src/system-agent/setup-inference-turn.test.ts` | S8@8, 66, 84; S10@7, 119, 126, 131, 154; S35@8, 66 |
| `src/system-agent/setup-inference-turn.ts` | S8@26, 402; S35@26, 330 |
| `src/system-agent/setup-inference.provider-install-owner.test.ts` | S10@12, 260 |
| `src/system-agent/system-agent.lifecycle.test.ts` | S8@10, 99; S35@10, 100 |
| `src/system-agent/system-agent.test-helpers.ts` | S36@15, 119 |
| `src/system-agent/system-agent.ts` | S8@159; S35@159 |
| `src/transcripts/status.metadata.test.ts` | S36@5, 96 |
| `src/transcripts/status.test.ts` | S36@9, 194, 256, 318 |
| `src/transcripts/status.ts` | S10@6, 24 |
| `src/tts/tts-request.preparation-resources.test.ts` | S7@15, 136 |
| `src/tts/tts-request.resources.test.ts` | S7@18, 207 |
| `src/tts/tts-streaming.resources.test.ts` | S7@16, 193 |
| `src/tts/tts-summary.selection.test.ts` | S7@13, 25 |
| `src/video-generation/runtime.resources.test.ts` | S7@16, 168 |
| `src/web-fetch/content-extractors.runtime.test.ts` | S7@3, 42 |
| `src/wizard/setup.migration-resources.test.ts` | S7@7, 15 |
| `src/wizard/setup.ts` | S32@597 |

### Predecessor-only retired consumers

Baseline coordinates use the symbol table’s retired/migrated dispositions; current counterparts are above.

| Baseline consumer | Retired symbol and baseline line |
| --- | --- |
| `extensions/signal/src/account-selection.ts` | S33@14; S33@4 |
| `extensions/signal/src/accounts.ts` | S33@11; S33@78 |
| `extensions/signal/src/setup-core.ts` | S33@320; S33@33 |
| `extensions/signal/src/setup-transport.ts` | S33@316; S33@9 |
| `extensions/signal/src/shared.ts` | S33@11; S33@35 |
| `src/channels/plugins/account-config-mutation.test.ts` | S5@286; S5@322; S5@358; S5@388; S5@413; S5@6; S15@275; S15@324; S15@360; S15@390; S15@407; S15@8 |
| `src/channels/plugins/account-config-mutation.ts` | S5@215; S15@196 |
| `src/commands/channels/remove.ts` | S5@223; S5@4; S15@209; S15@6 |

### Additional lexical and manual consumers

Retain means source disposition, not live execution.

| Consumer | Exact disposition |
| --- | --- |
| `apps/ios/Sources/Gateway/GatewaySettingsStore.swift:764`; `apps/ios/Sources/Gateway/KeychainStore.swift:37` | Exclude `deleteAccounts` homonym: Keychain deletion, no channel/native change. |
| `docs/plugins/manifest.md:102,261`; `docs/plugins/manifest/surfaces.md:353–362` | Retain documented manifest policy declaration. Snapshot remains its projection; no new manifest/config key. |
| `docs/plugins/sdk-channel-plugins/setup-and-config.md:91–130` | Changed public selector documentation. Documents optional channel context on resolveAccountKey and its absence from v2026.9.4. No new public name remains. |
| `docs/channels/signal.md:86` | Changed user guidance correctly describes collision refusal and preserved rows. This is CLI documentation, not a protocol field. |
| `extensions/clickclack/src/accounts.ts:86,122` | Retain explicit-normalizer SDK account/token-file reads; no creation mode. |
| `extensions/discord/src/accounts.ts:52`; `extensions/discord/src/token.ts:70` | Retain no-policy SDK account/token reads. |
| `extensions/discord/src/monitor/gateway-registry.ts:16,22,27,32`; `extensions/discord/src/monitor/presence-cache.ts:12,22,43,49` | Exclude local `resolveAccountKey` homonyms: runtime registry/presence partitioning, not the changed shared selector. The latter's generic accountKey uses are already separately listed in the PR. |
| `extensions/feishu/src/channel.ts:1130` | Retain custom no-op/unsupported delete; CLI rejects normalized no-op before effects. No shared-map survival check. |
| `extensions/googlechat/src/accounts.ts:71`; `extensions/imessage/src/accounts.ts:47` | Retain no-policy default/account reads through public wrapper. No creation mode. |
| `extensions/line/src/accounts.ts:88`; `extensions/line/src/group-keys.ts:52` | Retain no-policy account and group reads. |
| `extensions/line/src/config-adapter.test.ts:34` | Retain adapter delete control; shared owner rejects aliases admitted by its selector. |
| `extensions/matrix/src/account-selection.ts:130`; `extensions/matrix/src/matrix/account-config.ts:81` | Retain SDK channel normalizer; Matrix identity/storage unchanged. |
| `extensions/matrix/src/channel.setup.test.ts:277`; `extensions/msteams/src/channel.test.ts:79` | Retain registered configuration/delete controls and protocol. |
| `extensions/signal/openclaw.plugin.json:13` | Retain the sole Signal account-key policy declaration; disabled maintenance and active owner selection consume this via metadata. |
| `extensions/signal/src/account-selection.test.ts:191,198,264`; `extensions/signal/src/core.test.ts:1366` | Signal config.deleteAccount covers collision refusal; root-default/core deletion controls remain. |
| `extensions/slack/src/accounts.ts:93`; `extensions/slack/src/shared.test.ts:77,108` | Retain no-policy read and registered adapter/delete contract tests. |
| `extensions/sms/src/accounts.ts:103`; `extensions/sms/src/channel.test.ts:92` | Retain no-policy account read and registered hybrid deletion control. |
| `extensions/telegram/src/account-config.ts:15`; `extensions/telegram/src/token.ts:125` | Retain explicit-normalizer entry/token reads through SDK barrels; no Signal policy threading. |
| `extensions/twitch/src/config.ts:68,116`; `extensions/twitch/src/token.ts:64` | Retain normalized account/config/token reads; no creation mode. |
| `extensions/whatsapp/src/account-config.ts:13`; `extensions/whatsapp/src/doctor-contract.test.ts:104` | Retain default account wrapper and existing case-insensitive Doctor expectation. No Doctor transform change. |
| `extensions/zalo/src/token.ts:42` | Retain SDK entry read for token selection. |
| `src/channels/plugins/read-only.ts:209,325,383–391` | Lightweight adapter carries selected policy, rebinds input/output config and calls registered deletion. Propagates refusal without inferring success. |
| `src/channels/plugins/types.adapters.ts:92` | Synchronous delete returns config; ambiguity uses existing error path/result shape. |
| `src/commands/agents.providers.test.ts:106,125` | Existing account-read/config-adapter fixture; retained no-policy provider setup contract. |
| `src/commands/channels.plugin-install.test-helpers.ts:70` | Existing custom delete mock is fixture infrastructure, not real installation-policy proof. |
| `src/config/zod-schema.providers-whatsapp.ts:126` | Existing schema validation reads default account through unchanged no-policy wrapper. No schema or migration edit. |
| `src/plugin-sdk/account-core.ts:15`; `src/plugin-sdk/account-resolution-runtime.ts:5`; `src/plugin-sdk/routing.ts:33` | Retain public entry/normalized-entry barrels. They continue reaching the same selector. Shipped declaration compatibility is recorded in the matrix below. |
| `src/plugin-sdk/channel-config-helpers.test.ts:346,388,584,606,644,715,763` | Retain SDK scoped/hybrid deletion and return-contract controls. |
| `src/plugins/contracts/plugin-sdk-runtime-api-guardrails.test.ts:217` | Retain public runtime export fixture for `deleteAccountFromConfigSection`; no removed prepared API. |
| `src/plugins/loader.prefer-over.test.ts:43,139` | Retain preferred-plugin/manifest policy precedence fixture. It remains a useful sibling to maintenance-policy selection. |
| `src/plugins/manifest-registry.ts:460`; `src/plugins/manifest-types.ts:400`; `src/plugins/manifest.ts:259–260`; `src/plugins/plugin-metadata-snapshot.types.ts:32` | Retain declaration parsing/types/projection; no new policy declaration/field. |
| `src/status/status-text.ts:97` | Retain status formatting's normalized-entry read. No creation path or newly composed protocol field. |
| `src/wizard/i18n/locales/en.ts:518`; `src/wizard/i18n/locales/zh-CN.ts:502`; `src/wizard/i18n/locales/zh-TW.ts:502` | Retain localized delete prompts/error handling; no new locale key. |
| `test/buzz-account-config-mutation.test.ts:53` | Retain existing preparation helper case; new command claims use command suites. |

### Returned adapters and their registrations

Returned callbacks consume the shared deletion owner.

| Consumer | Exact disposition |
| --- | --- |
| `extensions/signal/src/shared.ts:32` | Changed registered scoped adapter removes direct policy constant; snapshot-backed shared delete selection/refusal is authoritative. |
| `extensions/whatsapp/src/shared.ts:59` | Retain scoped adapter; named deletion consumes shared owner, root cleanup retains configured field list. |
| `extensions/matrix/src/config-adapter.ts:18` | Retain scoped adapter and Matrix's registered account accessors; delete now consumes shared post-map admission. |
| `extensions/discord/src/shared.ts:86` | Retain scoped adapter and Discord accessors; shared deletion result is consumed without another survival check. |
| `extensions/zalo/src/channel.ts:142` | Retain registered scoped deletion. |
| `extensions/nextcloud-talk/src/channel.adapters.ts:19` | Retain registered scoped deletion. |
| `extensions/irc/src/channel.ts:103` | Retain registered scoped deletion. |
| `extensions/zalouser/src/shared.ts:32` | Retain registered scoped deletion. |
| `extensions/imessage/src/shared.ts:36` | Retain registered scoped deletion. |
| `extensions/googlechat/src/channel-base.ts:48` | Retain registered scoped deletion. |
| `extensions/mattermost/src/channel-config-shared.ts:55` | Retain registered scoped deletion. |
| `extensions/line/src/config-adapter.ts:11` | Retain registered scoped deletion. |
| `extensions/telegram/src/config-adapter.ts:35` | Retain registered scoped deletion. |
| `extensions/slack/src/config-adapter.ts:16` | Retain scoped base spread into Slack configuration; shared named-delete admission, existing channel-specific effects unchanged. |
| `extensions/tlon/src/channel.ts:58` | Retain hybrid adapter: named-account deletion consumes shared owner; configured default credential cleanup remains its existing contract. |
| `extensions/synology-chat/src/channel.ts:112` | Retain hybrid adapter with the same named/default distinction. |
| `extensions/feishu/src/channel.ts:488` | Retain hybrid base plus custom registered wrapper at `:1130`; do not mistake its custom no-op outcome for a shared-selector refusal. |
| `extensions/sms/src/channel.ts:71` | Retain hybrid named-account delete and default credential clearing contract. |
| `src/commands/channels.adds-non-default-telegram-account.test.ts:116` | Retain existing registered command fixture using returned scoped adapter; sibling promotion/naming proof is not new installation-policy evidence. |
| `src/auto-reply/reply/commands-allowlist.test.ts:137` | Retain returned adapter fixture for allowlist command behavior; does not exercise delete. |
| `src/commands/agents.providers.test.ts:125`; `src/plugin-sdk/channel-config-helpers.test.ts:410,435,739` | Retain factory-returned test consumers; SDK public adapter result shape unchanged. |

### Final consumers, hosts, and external declarations

| Consumer | Exact disposition |
| --- | --- |
| `src/commands/channels/status.ts:69`; `src/commands/channels/status-config-format.ts:81` | Final CLI status consumes Gateway or configured-account view. Cold status and selected transport establish the bounded deletion claim. |
| `src/gateway/server-methods/channels.ts:330,392,496` | Status/stop consumers; no delete RPC. CLI admission precedes registered stop. |
| `src/gateway/server-channels.ts:374,382` | Runtime account preparation consumes the selected account entry; cold start is the final state check after persistence. |
| `extensions/signal/src/sse-reconnect.ts:89`; `extensions/signal/src/client.ts:350–366` | Final recording boundary builds `/api/v1/events` and its account query from selected endpoint/phone. Exact/alias/legacy recorder observations discriminate actual transport identity. |
| `src/flows/channel-setup-navigation.ts:13`; `src/wizard/navigation-prompter.ts:304` | Generic awaited result consumers retain their contracts; the phase producer now declares its awaited result. |
| `src/system-agent/chat-wizard-host.ts:355,370,384,398` | Channel, skills, search and Gateway starts share hosted setup and its operation lifetime. Completion semantics stay intact; channel proof plus existing sibling tests bound the claim. |
| `src/system-agent/chat-turn-router.ts:453,456,459,462` | Dispatches to four hosted starts, independently of `wizard.start`; same metadata owner. |
| `src/gateway/server-methods/system-agent.ts:590` | `system-agent.chat` enters the chat router/host path under existing admission; shared hosted runner drops inherited runtime metadata and owns complete setup. |
| `src/system-agent/tui-backend.ts:433,447` | Terminal Gateway/search handoffs consume hosted resource lifetime; source disposition only. |
| `src/commands/agents.commands.add.ts:443`; `src/commands/configure.wizard.ts:707`; `src/wizard/setup.ts:597` | Local CLI callers inherit the operation owner and shared setup phases. |
| `src/commands/onboarding-plugin-install.ts:131`; `src/plugins/installed-plugin-index-store-write.ts:237`; `src/plugins/runtime.ts:690` | Invalidation producers revoke nested operation facts; admitted Gateway inventory stays stable. |
| `src/plugin-sdk/account-resolution.ts:19–23`; `src/routing/account-lookup.ts:19–51,94–119` | Remove candidate-only resolveChannelAccountKey export. Existing resolveAccountKey accepts optional channelId; map, ID, normalizer, policy and allowMissing retain their contracts, including reserved creation rejection. |
| `extensions/signal/package.json:95–102` | Unchanged support floors; published/candidate matrix below excludes candidate Signal on an old SDK. |
| `scripts/release-check.ts:121,753,767`; `scripts/fixtures/packed-plugin-sdk-setup-consumer.ts:1` | Retain the unchanged external setup consumer and compile owner. The shipped/candidate declaration matrix below records exact artifact applicability; SDK channel-context execution is covered separately. |

### Structural and retained-fixture consumers

| Consumer | Exact disposition |
| --- | --- |
| `test/scripts/plugin-sdk-surface-report.test.ts:138,163`; `scripts/plugin-sdk-surface-report.mts:373,509` | Public export/callable counts remain unchanged after removal of the candidate-only export; existing guards are retained. |
| `test/extension-test-boundary.test.ts:242`; `src/plugins/contracts/boundary-invariants.test.ts:331`; `scripts/check-tsgo-core-boundary.mts` | Project/type-graph guards retained. Real Signal agreement moves to root integration ownership through public facade loading. |
| `src/commands/doctor-config-preflight.plugin-persistence.test.ts:195,399`; `src/commands/doctor-plugin-registry-generation-repair.test.ts:94`; `src/gateway/config-reload.test.ts:6823`; `src/commands/onboard-quickstart-host.plugin-generation.test.ts:104` | Rewritten fixtures distinguish nested refresh from independent/admitted frozen consumers; durable-state rejection, Doctor non-restoration, full inventory and lease release remain asserted. |


### Current correction test consumers

These 561c1895 coordinates supersede historical test references above; C10 only shifts callback fixture lines.

| Consumer | Exact disposition |
| --- | --- |
| `src/plugins/test-helpers/install-account-policy.test-support.ts:4,39–59` | New fixture writes real manifest `channelAccountKeyPolicies`, calls `loadPluginMetadataSnapshot` and `clearPluginMetadataLifecycleCaches`. Used by CLI add `:1930`, setup flow `:1582` and hosted setup `:700` below. Installer simulation for registered-entry proof, not a production policy declaration. |
| `test/plugins/signal-account-policy.integration.test.ts:5,14–48` | Relocated Signal/core agreement: `withPluginMetadataSnapshotScope` selects an earlier policy-free owner over the real Signal manifest; loads the public Signal facade. Retires the round-1 core-only Signal import/scope row. |
| `src/channels/plugins/account-config-mutation.test.ts:5–8`; `src/channels/plugins/account-key-policy.test.ts:1–16` | Historical S4/S36 test coordinates are retired: no current removal-helper/real-Signal scope consumers here. Commands replace them in `src/commands/channels.add.test.ts:1417` and `src/commands/channels.remove.test.ts:362,385,417,491,557`; Signal agreement moves to the integration file above. |
| `src/routing/account-lookup.test.ts:3–96`; `src/commands/channels.add.test.ts:1930–2044`; `src/flows/channel-setup.test.ts:1582–1717`; `src/system-agent/hosted-setup.runtime.test.ts:700–851` | Current public-selector/scoped-policy consumers: SDK arguments, installed-policy final row/status and retained postwrite callbacks. Supersede old test positions; no new production owner. |
| `test/setup.signal.ts:7–16` | Parses the real Signal manifest with `loadPluginManifest` before the snapshot fixture; preserves policy and per-test scope/reset. Fixes raw-JSON category typing; no production change. |

### Deleted fixture fields

The filename heuristic finds 16 removed private fixture keys in `src/channels/plugins/account-config-mutation.test.ts` (base `89bf2a4e`), with zero surviving consumers. Shared contracts and same-word homonyms remain; C4 commands preserve the fixture behavior.

Baseline locations: `accountId:207,213,277,282,300,324,409`; `accountIds:330,396`; `action:278,360,390,396,410,421`; `allowTopLevel:352`; `config:254,314,345,384`; `deleteAccount:256,316,347,384`; `gateway/startAccount:272`; `listAccountIds:255,315,346`; `nextCfg:212`; `nextConfig:367`; `prevCfg:211,299`; `resolveAccountId:180`; `sectionKey:351`; `setAccountEnabled:317,348`; `value:366`.

census: generic accountId reviewed — 0 callers listed
census: generic accountIds reviewed — 0 callers listed
census: generic action reviewed — 0 callers listed
census: generic allowTopLevel reviewed — 0 callers listed
census: generic config reviewed — 0 callers listed
census: generic deleteAccount reviewed — 0 callers listed
census: generic gateway reviewed — 0 callers listed
census: generic listAccountIds reviewed — 0 callers listed
census: generic nextCfg reviewed — 0 callers listed
census: generic nextConfig reviewed — 0 callers listed
census: generic prevCfg reviewed — 0 callers listed
census: generic resolveAccountId reviewed — 0 callers listed
census: generic sectionKey reviewed — 0 callers listed
census: generic setAccountEnabled reviewed — 0 callers listed
census: generic startAccount reviewed — 0 callers listed
census: generic value reviewed — 0 callers listed

### Correction coordinates and completed merge census

The a6de2d82 delta had 77 source/17 test references and 11 project-local gaps. Completed query: merge `730d8f0e4b1b35bbccffa60474e9fc7485751b08`, head `561c1895e26f33230ec298ce51e23d1de60061a8`, tree `7d9cd60e3fa5d856ab12343d489965c95dc7eeb1`. Six projects loaded: core, Signal, UI, extension tests, SDK package and root. Across 34 positions: 159 resolved/45 project-local gaps; all 34 resolve in root. Exit 0; no stderr. References: 3,752 raw/1,816 unique across 413 files (532 source, 1,284 test/support). Retained `typed-census-merge-730d8f0e-complete-coverage.json` names all 131 unselected projects. These are limits, not zero consumers or execution/typecheck proof. Native, string, facade and dynamic consumers have manual/lexical dispositions. Queried owners and proof-relevant paths match candidate to merge; no unexpected production consumer. Source coordinates below retain the a6de2d82 delta.

| Symbol | Current source locations |
| --- | --- |
| S20 | `src/routing/account-lookup.ts:43,72,84,89`; `src/config/channel-account-config.ts:3,83`; `src/channels/plugins/config-helpers.ts:8,197`; `src/plugin-sdk/account-resolution.ts:19`; `extensions/signal/src/account-selection.ts:1,7` |
| S22 | `src/routing/account-lookup.ts:19,27,35,56`; `src/config/channel-account-config.ts:4,76`; `src/config/group-policy.ts:3,75`; `src/channels/plugins/config-helpers.ts:9,87,125,143,190`; `src/channels/plugins/helpers.ts:9,57,63`; `src/channels/plugins/setup-helpers.ts:8,50,93,311,370`; `src/channels/plugins/account-config-mutation.ts:5,97`; `src/config/channel-doctor-helpers.ts:3,196`; `src/plugin-sdk/allowlist-config-edit.ts:8,197` |
| S34 | `src/commands/config-validation.ts:57`; `src/flows/channel-setup.ts:27,106,289,439,449,582,986,1088,1105`; `src/commands/channels/add-wizard.ts:24,205`; `src/commands/channels/add.ts:29,274`; `src/commands/channels/remove.ts:21,106` |
| S24 | `extensions/signal/src/account-selection.ts:3,16`; `extensions/signal/src/config-compat.ts:6,329,340,390,402,514`; `extensions/signal/src/setup-core.ts:30,365`; `extensions/signal/src/account-key-repair.ts:5,36` |
| S23 | `extensions/signal/src/account-selection.ts:12`; `extensions/signal/src/accounts.ts:11,292`; `extensions/signal/src/setup-transport.ts:9,89,123,124`; `extensions/signal/src/setup-core.ts:30,215`; `extensions/signal/src/config-schema.ts:16,164` |

## Invalidation

- Delete admission: `src/channels/plugins/config-helpers.ts:143` re-resolves before `applyChannelAccountRemoval` invokes stop/lifecycle; refusal causes no write/success. Existing publication/reload and cold restart consume successful writes.
- Install: `src/plugins/plugin-metadata-lifecycle.ts:244` invokes operation revocation before its active-Gateway guard. `src/plugins/current-plugin-metadata-snapshot.ts:197` visits enclosing caches, excluding admitted runtime caches; `src/plugins/plugin-cache.ts:146` clears facts, retaining modules/instances.
- Custody: `src/flows/channel-setup.ts` loads callbacks into its enclosing operation under the install lease. `src/gateway/server-methods/wizard.ts:61` and `src/system-agent/hosted-setup.runtime.ts:49` own operations through runner/hook settlement.
- Final read: `src/flows/channel-setup.ts:90` rereads committed config and scopes metadata before collected hooks. Ordinary publication does not revoke admitted scopes.

## Contention

No new lock/queue/writer. Stop follows deletion admission; hosted admission/cancellation remain through cleanup. Deferred completion/cancellation pass; no full concurrency-stress claim.

## Tests

Tier L. C10/C12 at 623bd36f: 128 tests/5 files/4 shards pass (35.47 s): selector, CLI add, hosted setup and both Signal suites. Three-file direct Oxlint and native review pass; CI core types/lint pass; root test types require the fixture repair. Retained: 778 tests/14 files/6 shards, 10 SDK surface tests, plugin-import/core graph checks pass; budgets unchanged. Fixture parser: 17 Signal/integration tests pass; root types await CI.

| Correction / current test entry | Retained behavior; PASS |
| --- | --- |
| C2 `src/gateway/server-methods/wizard.test.ts:149`: `wizard.start` setup/channels/cancel | Type-only fixture repair; three callback-lifetime/Gateway-preservation cases unchanged. |
| C3 `test/plugins/signal-account-policy.integration.test.ts:14`: Signal `config.resolveAccount` plus SDK reader | Relocated competing-owner case loads real Signal via public facade; earlier policy-free owner wins. |
| C4 `src/commands/channels.add.test.ts:1417`: `channelsAddCommand` | Replaces helper omission/normalization cases: omitted ID reaches plugin, Work selected, writer uses work, lifecycle/result retain Work. |
| C4 `src/commands/channels.remove.test.ts:362,385,417,491,557`: `channelsRemoveCommand` | Unknown delete/disable have no effects; unauthored listed default disables; normalized delete preserves sibling/lifecycle; fresh no-op and unsupported delete/disable never stop/write/run hooks. |
| C6 `src/commands/channels.add.test.ts:1930`; `src/flows/channel-setup.test.ts:1582`; `src/system-agent/hosted-setup.runtime.test.ts:700` | CLI add, setupChannels, ChatWizardHost.startChannel carry installed manifest through original-row rename, final config/status and retained postwrite callback; CLI/chat preserve executable Gateway inventory. |
| C9 `src/commands/doctor-config-preflight.plugin-persistence.test.ts:138,267` | runDoctorConfigPreflight: five scope/replacement rows plus alpha/beta: nested refresh vs independent reader, full inventory/exact durable leaf and lease release. |
| C9 `src/gateway/config-reload.test.ts:6774`; `src/commands/doctor-plugin-registry-generation-repair.test.ts:76` | startGatewayConfigReloader/applyPluginLifecycleChange and maybeRepairPluginRegistryState: nested/independent durable-input rejection/no acceptance and no restoration. |
| C9 `src/commands/onboard-quickstart-host.plugin-generation.test.ts:19` | runQuickstartForegroundGateway: mutable/pinned first inventories see install; mutable caller refreshes, admitted generation remains old. |

C9's 13 changed-family rows cover all seven former failures; no terminal safeguard deleted. Signal collision test replaces row-preservation-only with refusal/no takeover; removal validates before stop, unsupported deletion never stops, and obsolete prepared-wrapper assertions move to command behavior.

Red evidence is claim-specific. Historical lease-ancestry and wizard lifetime cases fail prior owners. C6 CLI before phase repair reads no selected account immediately after install; candidate reaches correct persistence/hooks. Historical setup/hosted reds show callback-custody/scope failure, not a wrong final row. C2 type repair, C3 relocation, C4 entry replacements and C9 fixture ownership are not each claimed red; unchanged publication-preservation cases pass.

C1 models awaited results; C8 forwards arguments into one policy lookup. The a6de2d82 declaration build predates test-only 561c1895. C12 replaces parameter assignment with an equivalent local; explicit policy still avoids the sole scoped lookup. C10 types two registered callbacks for nullable/omitted IDs through existing normalization, makes work-phone reads explicit and retains all assertions. C11 updates census coordinates. Accepted runtime/old-state proof remains bound to its recorded head; no new execution is implied.

Real CLI and cold Gateway proof at `9a24813986c8fa440e144b35af7ee0d374f11d4d`:

| Operation | Pinned main | Candidate |
| --- | --- | --- |
| Delete colliding Signal account | Exit 0; cold start activates Shadowed identity | Exit 1 names both keys; config unchanged; Selected identity stays running and survives cold restart |
| Delete one stored identity | Positive control | Exit 0; cold start not configured/running; zero recorder requests |
| Delete with disabled Signal plugin | Maintenance control | Exit 1 names both keys; config unchanged |
| Setup `constructor`, `__proto__`, `prototype` | Reserved selector can report a default account | All exit 1; config bytes unchanged |
| Doctor preview and repair | Existing collision preservation contract | Preview leaves account map unchanged; repair preserves colliding/dormant rows and normalizes the unambiguous alias |

| Consumer / support floor | State artifact producer | Operation | Result |
| --- | --- | --- | --- |
| Candidate Signal runtime; existing own-number account-map format | Actual v2026.9.4 source CLI at `3a9d69db30` | Cold start and status from old source-written state | Same legacy phone identity and `/legacy` transport; configured/running/connected |

| Declaration consumer / unchanged floor | Shipped artifact | Candidate artifact / operation | Result |
| --- | --- | --- | --- |
| Unchanged packed setup consumer; Node 24, TS 6.0.3; Signal minHostVersion >=2026.6.9, pluginApi >=2026.9.4 | openclaw@2026.9.4; job 103534002152, run 34686394191 | a6de2d82 canonical strict-smoke declarations; same setup/setup-runtime consumer through package exports, strict NodeNext, skipLibCheck:false | Both PASS; candidate 153 public subpaths/build budgets PASS |

Both consumer inputs have SHA-256 `c91b6daa1dfeb7a09314829c925b27419626b6012eaea2da9433e9f3a2a69ffd`. Existing floors stay unchanged. v2026.9.4 lacks resolveAccountKey, so channel context is unavailable there; no candidate Signal-on-old-SDK claim. Candidate uses existing public resolveAccountKey, not a new export. Argument tests cover map/ID/channelId, explicit policy, normalizer/no-channel behavior, allowMissing and blocked creation.

Old-source state proof is separate from updater/old-host SDK support. Dev launcher produced CLI/Gateway proof; disposable-container declarations cover the external consumer. Doctor also ran its existing Control UI asset repair. Runtime proof stamps stayed fixed. Synthetic local transport proves identity, not live Signal delivery.

Process failures: update timeout also reproduces on main. Duplicate-help timed out in CI; its one authorized focused retry at 623bd36f passes (1 selected/34 skipped, 1.30 s). Cause remains unresolved; no further manual retry.

Credit: the adversarial regression round; no external reporter.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-12 20:54:39 +05:30
Peter Steinberger
a02a33d523
fix: support large SQLite worker commands with bounded transport (#146019)
* fix: support large SQLite worker commands with bounded transport

* refactor: keep SQLite transfer handles in the leaf contract
2026-09-12 08:02:55 -07:00
Ayaan Zaidi
4dd1723ba0
fix: Nostr profile actions fail for paired dashboard operators (#145932)
## What Problem This Solves

Fixes an issue where paired dashboard operators could not save or import a Nostr profile when their browser held only its device credential. Save & Publish and Import from Relays each returned HTTP 401, then displayed `e?.trim is not a function`.

The dashboard handoff in `docs/web/control-ui/connect-and-pair.md`, paired-operator Control UI read authorization, and profile editor in `docs/channels/nostr.md` establish this contract. The defect was reproduced on pinned main `3b88500581` through the real browser and Gateway.

Related: #138975 preserves recovery when a second credential exists; this fixes the device-only case. #105781 concerns import cancellation and drafts and remains separate. Related #78712 discusses shared-secret trusted-operator defaults; this repair preserves that shipped policy. Found by the adversarial round; no external reporter.

## Why This Change Was Made

The shared HTTP authorization owner now verifies current paired-operator credentials for plugin routes and passes their verified scopes to the existing runtime scope owner. Nostr keeps its admin requirement. Request headers cannot expand a device grant; ordinary plugin routes retain their write ceiling.

The existing plugin request scope also carries a Gateway-owned `revalidate` callback. Nostr, Admin HTTP RPC, Beam, and Geolocation call it after input reading/validation and before starting effects; Nostr checks after the publish queue wait and again before saving a published or imported profile. It verifies the original device grant through the same credential checker, writes the standard Gateway 401 on rejection, and stops the handler. There is no new registration option, config key, or contract version. This checkpoint does not cancel external work already in progress.

The shared Control UI JSON response boundary checks parsed objects, decodes Gateway error envelopes once, and supplies message plus HTTP status. The import adapter narrows profile text fields while preserving null values and extra fields. Channels and Browser Download use that result. Nostr-local error decoding and string-typed error assumptions are removed; profile validation details remain visible.

The decision "whether a shared or paired-device credential authenticates an operator HTTP request" is made by exactly one mechanism at `src/gateway/http-auth-utils.ts:241` (`checkHttpOperatorCredentials`).

The decision "whether an admitted device grant remains valid before handler effects" is made by exactly one mechanism at `src/gateway/http-auth-utils.ts:241` (`checkHttpOperatorCredentials`), shared by admission and the Gateway-owned request-scope callback.

The decision "how a Gateway JSON error becomes UI text with HTTP status" is made by exactly one mechanism at `ui/src/app/control-ui-auth.ts:6` (`readControlUiJsonResponse`).

## User Impact

Paired operators can publish and import their Nostr profile with their existing device session. Rejected credentials show `HTTP 401: Unauthorized`. Configured-token recovery remains available. No schema, migration implementation, config key, dependency, or protocol version changes are included.

## Evidence

| Real entry point | Pinned main | Candidate |
| --- | --- | --- |
| Startup-token dashboard, device-only browser: Save & Publish | One 401; trim exception | 200, persisted and published |
| Same paired browser: Import from Relays | One 401; trim exception | 200, saved and rendered |
| Auth disabled, direct dashboard: Save and Import | 200 / 200 | 200 / 200, no Authorization |
| Configured shared token after rejected device credential | Existing recovery contract | Each action: real 401 then 200 |
| Wrong credential | Object error envelope | Visible HTTP 401 and Unauthorized |
| Browser panel Download, rejected media credential | Decoder regression covered by rendered test | Real 401 rendered as HTTP 401: Unauthorized; recovery 200 |

Independent browser acceptance passed the bounded profile clauses on packaged candidate `669b3903`, before the additional revalidation correction. Its UI owner and callers are unchanged in the current candidate. Sanitized before/after screenshots and pass-through HTTP captures are retained with the review evidence. Synthetic profiles and a local relay were used; no external profile was published.

The earlier `eac0c373` package was produced with normal package preparation and declarations enabled in an isolated container. The canonical tarball checker passed. The actual v2026.9.4 CLI updated from the verified initial candidate tarball, exited 0, and finished its output. The UI correction was rebuilt and checked separately. After the first revalidation correction, that package ran Save and Import against a fresh copy of the preserved old state with the exact original v2026.9.4 bearer. Both returned 200; no pairing approval or token rotation occurred. All retained source-fixture hashes remained unchanged. Device identity, token bytes, scopes, and Gateway auth configuration remained unchanged. Browser automation resumed from the saved authentic old browser state; uninterrupted same-window recovery is not claimed.

On the preserved old-pairing fixture, both actions returned 200, but Import returned older local text in its merged payload; the UI displayed that value. That lane proves older-pairing authority and returned-data rendering, while the startup, configured-token, and auth-disabled lanes prove the new-text round trip. Package metadata has a null commit field; retained clean-source and tarball hashes bind the tested artifact to this candidate.

The `eac0c373` packaged Gateway also passed the delayed-revocation regression and Beam sibling. Each request was admitted while its body remained incomplete. Public device revocation completed before body completion. Nostr PUT and Beam POST then returned exactly `{"error":{"message":"Unauthorized","type":"unauthorized"}}` with HTTP 401. Nostr relay count and saved profile stayed unchanged; Beam's entire stored row, including retention metadata, stayed unchanged. Valid controls returned 200 and persisted. Fresh requests using the revoked tokens returned 401. Both isolated Gateways exited 0 and their ports closed.

The auth-disabled dashboard handoff separately closed with code 1000 before the editor loaded. Direct dashboard access and a backend socket worked. That handoff observation is retained separately and is not counted as a passing control.

The later CI correction `2d7774c3` only reuses structurally identical request/profile types and the existing test promise helper, and renames a shadowed test variable. Fresh native review verified unchanged authorization statements and API shapes; the exact eac0 package and runtime evidence remains bound to its original artifact. All 26 affected core tests and focused lint pass after this correction. CI owns the full type checks. No package or browser rerun is claimed for the type-only correction.

The final source correction is `7285ad188c241ed9a51f9646967d1a2ba9070539`. Its fresh isolated package build includes SDK declarations; all 153 SDK export checks and the canonical tarball checker passed. The build container was removed and a fresh absence check passed. Package SHA-256: `0011e2b13708d8af48bee07c8588f736a95577b89de2f33bfc85a4d7b19420aa`. Metadata commit is null; the clean source tree and tarball digest bind this artifact. The prior browser and actual old-updater receipts retain their original tested identities.

Final `7285ad18` packaged proof passed all three affected runs, once each. With the first relay acknowledgement held, a second Save was admitted and queued, then publicly revoked; after releasing the first publication, the second returned the standard HTTP 401 envelope with no second relay event and no config mutation. In a separate Save, the relay had already received the event before revocation; releasing its acknowledgement produced HTTP 401 and left config unchanged. That publication remains a completed partial outcome. Pending-body Nostr PUT and Beam POST also returned the same 401 with no publication/profile or Beam-row change; valid controls returned 200. The exact preserved v2026.9.4 bearer performed Save (200/persisted) and Import (200/saved) on the final package without pairing or rotation. The known local-over-imported text precedence remains; fresh imported text round-trip is not claimed in that fixture. All three isolated Gateways exited 0 and their ports closed.

## Consumers

| Consumer | Disposition |
| --- | --- |
| `extensions/nostr/src/nostr-profile.ts:84,133` | Retain kind-0 event creation/signing and the per-relay publication boundary. `successes`, `failures`, `eventId`, and `createdAt` describe the publication operation already started. A later config-save rejection does not undo a relay event. |
| `extensions/nostr/src/nostr-bus.ts:676,694` | Retain the publication owner’s previous-timestamp read, relay-result mapping, and publication-state write. Recording the actual publication remains valid when the later independent profile-config save is rejected. |
| `extensions/nostr/src/nostr-state-store.ts:103,114` | Retain account-keyed publication-state reads/writes and the existing stored format. Publication bookkeeping is separate from the saved profile configuration. |
| `extensions/nostr/src/nostr-profile-import.ts:86,238` | Retain relay subscription, profile validation, and local-first merge. The handler checks before import starts and again before saving its result. The older-state fixture’s imported fresh text and older merged text are distinct observed fields; no merge-precedence repair is claimed. |
| `extensions/beam/src/store.ts:15,23` | Retain the sessions namespace, retention policy, and forwarding of the upload update callback to the existing keyed store. |
| `src/plugin-state/plugin-state-store.ts:167,176,229` | Retain the asynchronous interface around the synchronous keyed update. After the handler’s authority check, this facade starts the existing synchronous update without another awaited queue. |
| `src/plugin-state/plugin-state-store.sqlite.ts:541` | Retain the transaction that selects the current Beam row, computes its replacement, writes value/expiry, and applies limits. Final revoked-request proof compares the whole row, including retention metadata, rather than only its payload. |
| `src/plugins/runtime/runtime-config.ts:8; src/config/mutate.ts:1405; extensions/nostr/index.ts:58` | Retain the lazy adapter and existing config-mutation owner used by Nostr’s registered `updateConfigProfile` callback with `afterWrite: { mode: "auto" }`. Save and Import pass a fresh authority check before this independent operation starts and await its result before reporting persistence. Existing config locking, commit, and observer behavior remain unchanged; cancellation inside an already-started operation is not claimed. |

The original BASE query used BASE production with candidate tests and is retained only as historical mixed-tree evidence. The corrected declaration census uses the immutable complete BASE source/test tree at `3b88500581`: all 16 original positions resolved in explicit root/test programs, yielding 248 raw references and 124 unique records. It recovered the omitted BASE `nostr-profile-ops.test.ts:128,136,148` calls; their exact helper-result assertions were retired in favor of rendered Channels and real-browser outcomes. All immutable BASE blobs matched before and after. The 136 unselected configurations remain explicit independent-resolution gaps. Unaffected candidate and integration queries retain their original bindings; they are not relabeled as current queries.

- `src/gateway/http-auth-utils.ts`: shared/device verification and request-local authority; removed `verifyControlUiDeviceReadToken` has no retained alternate implementation.
- `src/gateway/http-utils.ts`: type/function re-exports and session/profile authorization remain compatible.
- `src/gateway/http-endpoint-helpers.ts`, `models-http.ts`, `openresponses-http.ts`, and `sessions-history-http.ts`: generic HTTP callers retain their existing credential and owner contracts.
- `src/gateway/control-ui.ts`, `control-ui-plugin-assets.ts`, `plugin-icon-http.ts`, and `user-profiles-http.ts`: existing Control UI read/media/avatar callers use the shared credential mechanism; their route guards remain.
- `src/gateway/server-http.ts`, `server-http-plugin-auth.ts`, and `server-runtime-state.ts`: carry verified request context into dispatch.
- `src/gateway/server/plugins-http.ts` and `server/plugin-route-runtime-scopes.ts`: propagate verified scopes to the registered plugin client; trusted routes keep method-specific guards, ordinary routes keep their write ceiling.
- `src/gateway/server-http-upgrades.ts`: still uses generic HTTP authorization and gains no device-token admission.
- `extensions/nostr/index.ts`, `extensions/admin-http-rpc/index.ts`, and `extensions/diagnostics-prometheus/index.ts`: dynamic trusted-operator consumers retain their admin/method/read checks. QA trusted-operator registrations also consume this dispatcher. Ordinary Gateway-authenticated routes in Beam, Team Reports, and Geolocation retain their existing route guards and write ceiling.
- `ui/src/app/control-ui-auth.ts`: owns JSON error decoding; existing credential ordering and retry conditions remain.
- `ui/src/pages/channels/nostr-profile-ops.ts` and `channels-page.ts`: Save/Import consume decoded text; validation data and current-operation checks remain. `NostrProfileHttpResult` is removed without an alias. Form callback registration reaches the actual Save/Import buttons through `view.detail.ts`.
- `ui/src/components/browser/browser-panel-download.ts` and `browser-panel-render.ts`: failed media fetches reach the visible alert through the shared decoder; successful blobs and native downloads retain their existing handling.
- `ui/src/i18n/locales/en.ts`: removes unused `updateFailedStatus` and `importFailedStatus`; no source reader remains. Generated translations retain their existing translation-workflow ownership.
- Returned test readers: `src/gateway/server/plugin-route-runtime-scopes.test.ts`, `src/gateway/server/plugins-http.runtime-scopes.test.ts`, `ui/src/pages/channels/nostr-profile-ops.test.ts`, and `ui/src/components/browser/{browser-panel-download,browser-panel-native}.test.ts`. Additional field-query readers are `src/gateway/http-auth-utils.test.ts`, `http-endpoint-helpers.test.ts`, `http-utils.request-context.test.ts`, and `server/plugins-http.suspension-admission.test.ts`. These fixtures/assertions retain route ceilings, request context, request lifecycle, download, and native behavior coverage. Added rendered tests are listed below.
- `src/gateway/plugin-icon-http.test.ts:26`: retain the lexical-only read-auth mock; icon tests preserve the existing call/return contract and do not prove credential verification.
- `src/gateway/user-profiles-http.test.ts:14,28,117`: retain the mock and avatar authorization assertions, including required `users.list`; `{}`/null results remain valid route fixtures, without a paired-token proof claim.
- `src/gateway/control-ui-assistant-media-policy.test.ts:24,70`: retain the mocked `authMethod`/`operatorScopes` result; this suite tests media policy, not credential selection, and its result shape is unchanged.
- `ui/src/pages/channels/view.nostr-profile-form.ts:181,269`: final form displays page-state error/success text and binds Save/Import callbacks; it neither parses nor rebuilds the HTTP error.
- `extensions/nostr/src/nostr-profile-http.ts`: retain admin, loopback, and origin checks for PUT/Import and await the profile writer before reporting persisted/saved; the callback consumes Gateway authority after queue waiting and before independent effects and adds no local device verifier.
- `extensions/qa-lab/test-fixtures/current-requester-subagent-plugin/index.js:51`: retain the trusted-operator Gateway-auth registration as a dynamic runtime consumer; no fixture or live-execution claim changes.
- `extensions/qa-lab/test-fixtures/codex-hook-context-proof-plugin/index.js:38`: retain the existing dispatcher contract, with no private auth import or live-execution claim.
- `extensions/qa-lab/test-fixtures/self-yield-followup-subagent-plugin/index.js:56,130,183`: retain all three trusted-operator registrations and their existing dispatcher contract; no new exemption or execution claim.
- `extensions/admin-http-rpc/src/handler.ts`, `extensions/beam/src/http.ts`, and `extensions/geolocation/src/lookup-route.ts`: consume the same request-scope revalidation before Gateway dispatch, state update, and lazy database loading respectively. Prometheus and Team Reports handlers read only; Geolocation's shared cache maintenance remains service-owned once started. Unchanged plugin-auth webhooks do not enter the new device-credential path.

The earlier prepush query has its own retained coverage inventory; it is not relabeled as the final census. In that inventory, source-root membership shows 132 of the 133 unselected configurations add no files outside the loaded root; their independent module resolution remains unqueried. The remaining scripts config adds 753 roots, checked lexically; its sole match is an unchanged test benchmark path. The loaded root contains the affected repository TypeScript, including plugin and test sources. Native code, strings, generated output, and external plugins require the manual contract trace; no named SDK export or transport field is added. The existing request-scope type gains the documented optional revalidation callback. Admin HTTP RPC, Prometheus, native apps, and QA fixtures were traced but are not claimed as live-tested.

| Shipped consumer | Support floor / artifact | Operation | Result |
| --- | --- | --- | --- |
| v2026.9.4 browser/device state | Released CLI → b7ff package; preserved bearer → final 7285 package | Historical actual update, then current Save/Import authority | PASS; old merged-text behavior retained |
| Current paired browser | 669b package/UI; UI unchanged in final 7285 | Device-only Save/Import | PASS on 669b; final 7285 packaged HTTP controls also pass |

The unchanged response boundary has a supplemental typed census from UI correction `669b3903`, the prior candidate, and the pinned baseline: 486 reference records, each accounted for. All 57 applicable root/test/UI positions resolved in that bound correction tree. The 38 core/Nostr exclusions remain explicit because those programs exclude private UI files. Imported and merged profiles have one private payload guard; all returned readers remain in the four UI owner/caller modules listed above.

The final comparison base is `93a5d82275`. All authored source/test baseline blobs match the original reproduction base; two inherited assertion-baseline deletions are separate. The current contribution spans 21 authored files, while the original red and typed-baseline evidence remains pinned to `3b88500581`.

Revalidation reference census: candidate `eac0c373` and original BASE `3b885005`, with root, test, core, Nostr, Admin HTTP RPC and Geolocation projects. Candidate returned 1,860 records (773 exact reader groups); BASE returned 1,670 (700 groups). Both exited 0, with no ambiguous queries or tool failures. All returned files are named below.

- **Effect handlers and registration exports:** The four changed bundled effect handlers retain their existing registration owners. Nostr PUT checks after body validation and queue waiting before publish, then again before config save; Import checks before relay I/O and again before config save. Nostr GET remains read-only. Beam checks before keyed-store update; Admin before Gateway dispatch; Geolocation before lazy database/cache work. Revalidation rejection stops effects; Nostr inner and outer catches preserve an ended 401. Tests remain direct handler consumers. Nostr index.ts resolves api.ts by a string export, so typed references alone miss that registration edge; the source-reviewed lazy registration is recorded separately. Files: `extensions/admin-http-rpc/index.ts`, `extensions/admin-http-rpc/src/handler.test.ts`, `extensions/admin-http-rpc/src/handler.ts`, `extensions/beam/index.ts`, `extensions/beam/src/beam.test.ts`, `extensions/beam/src/http.ts`, `extensions/beam/src/mirror-retry.test.ts`, `extensions/geolocation/index.ts`, `extensions/geolocation/src/lookup-route.test.ts`, `extensions/geolocation/src/lookup-route.ts`, `extensions/nostr/api.ts`, `extensions/nostr/src/nostr-profile-http.test.ts`, `extensions/nostr/src/nostr-profile-http.ts`.

- **Revalidation capability producer, transport, and readers:** The auth owner creates one optional callback only for admitted device-token requests. The route scope copies it only for gateway-auth routes. Its seven production call sites serve five effect branches in four handlers; Save and Import each check again before their later independent config save. The paired-device regression fixture calls the same scope capability. There is no callback for shared credentials or plugin-auth routes. Files first listed in this group: `src/gateway/http-auth-utils.paired-device.test.ts`, `src/gateway/http-auth-utils.ts`, `src/gateway/server/plugins-http.ts`, `src/plugins/runtime/gateway-request-scope.ts`.

- **Credential and original-scope checks:** The existing HTTP credential owner handles initial admission and revalidation. The closure captures the bearer and admitted scope copy, passes original scopes to the current device verifier, and requires a successful device-token result. Current token scopes and original scopes both reach the pairing verifier. A current shared-secret match cannot revive a revoked device grant. Initial admission retains rate accounting; revalidation deliberately omits the limiter. BASE uses verifyControlUiDeviceReadToken and lacks the central checker/new fields, recorded as explicit declaration absences rather than zero readers. The auth-result declaration query also resolves its owning result-property references, all retained in the raw accounting. Files first listed in this group: `src/gateway/server/plugin-route-runtime-scopes.ts`.

- **HTTP auth types, server factory, and current-auth routing:** Core aliases, endpoint signatures, upgrade types, and test fixtures keep their prior required fields. The optional callback does not change core endpoint admission. Only the plugin HTTP authorizer attaches it. createGatewayHttpServer forwards its existing current-auth getter; server-runtime-state remains the serving owner supplying that getter. Both plugin route scope construction paths use the same factory. Static-auth test factories keep their existing fixed-auth contract. Files first listed in this group: `src/gateway/http-endpoint-helpers.ts`, `src/gateway/http-utils.ts`, `src/gateway/models-http.ts`, `src/gateway/openresponses-http.ts`, `src/gateway/provider-browser-auth/persistence.integration.test.ts`, `src/gateway/server-http-plugin-auth.ts`, `src/gateway/server-http-upgrades.ts`, `src/gateway/server-http.canvas.test.ts`, `src/gateway/server-http.node-workspace-transfer.test.ts`, `src/gateway/server-http.probe.test.ts`, `src/gateway/server-http.rejection-transport.test.ts`, `src/gateway/server-http.request-trace.test.ts`, `src/gateway/server-http.test-harness.ts`, `src/gateway/server-http.ts`, `src/gateway/server-http.upgrade-claim.test.ts`, `src/gateway/server-runtime-state.ts`, `src/gateway/server.plugin-node-capability-auth.test.ts`, `src/gateway/server.preauth-hardening.test.ts`, `src/gateway/server.public-worker-ingress.test.ts`, `src/gateway/server/plugins-http.runtime-scopes.test.ts`, `src/gateway/sessions-history-http.ts`, `src/gateway/worker-environments/node-workspace-transfer.test-support.ts`.

- **Standard unauthorized response owner:** sendUnauthorized remains the unchanged standard JSON 401 writer. The new closure invokes it before throwing; existing auth-failure and watch-node consumers retain their prior response behavior. No alternate error encoder or response owner was added. Files first listed in this group: `src/gateway/http-common.test.ts`, `src/gateway/http-common.ts`, `src/gateway/watch-node-http.ts`.

- **Existing request-scope type, getter, runner, and consumers:** The request-scope storage, getter and runner implementations are unchanged from original BASE. Existing registry, plugin identity, client, context, resolver and node-authority readers retain those fields and behavior; the callback is additive and optional. Existing spread-based scope transport preserves the closure, whose ended/destroyed-response guards prevent retained authority from being used after response expiry. Registry/context projection helpers retain their established inheritance rules. The only new behavior consumers are the four effect handlers and the paired-device fixture listed above. Public SDK barrels remain aliases to the same getter. The full file lists include every import, export, type, test fixture and execution reader returned by either side; no reader is discarded as merely a test. Files first listed in this group: `extensions/browser/src/browser/extension-relay/gateway-relay-route.ts`, `extensions/diagnostics-prometheus/src/service.ts`, `extensions/nostr/runtime-api.ts`, `extensions/nostr/src/nostr-profile-http-runtime.ts`, `extensions/team-reports/src/http.ts`, `packages/plugin-sdk/src/plugin-runtime.ts`, `src/acp/control-plane/spawn.test.ts`, `src/agents/embedded-agent-runner/compact.foreground-resources.test.ts`, `src/agents/embedded-agent-runner/run.plugin-runtime-refresh.integration.test.ts`, `src/agents/harness/host-capability.node-authority.test.ts`, `src/agents/harness/host-capability.test.ts`, `src/agents/harness/host-capability.ts`, `src/agents/harness/node-execution-authority.ts`, `src/agents/harness/selection.test.ts`, `src/agents/harness/session-deletion.ts`, `src/agents/isolated-completion.resources.test.ts`, `src/agents/isolated-completion.test.ts`, `src/agents/main-session-recovery/main-session-restart-recovery-marking.test.ts`, `src/agents/mcp-auth-profile.integration.test-support.ts`, `src/agents/mcp-connection-resolver.ts`, `src/agents/openclaw-plugin-tools.ts`, `src/agents/runtime-plugins.test.ts`, `src/agents/runtime-plugins.ts`, `src/agents/session-maintenance/run.ts`, `src/agents/subagents/announce/subagent-announce.requester-settle-dispatch.test.ts`, `src/agents/subagents/registry/subagent-registry.test.ts`, `src/agents/subagents/spawn/acp-spawn.authority.test.ts`, `src/agents/subagents/spawn/subagent-spawn-cleanup.test.ts`, `src/agents/subagents/spawn/subagent-spawn-cleanup.ts`, `src/agents/subagents/spawn/subagent-spawn-gateway.test.ts`, `src/agents/subagents/spawn/subagent-spawn-gateway.ts`, `src/agents/subagents/spawn/subagent-spawn.authority.test.ts`, `src/agents/subagents/spawn/subagent-spawn.in-process-gateway.test.ts`, `src/agents/subagents/spawn/subagent-spawn.preparation-authority.test.ts`, `src/agents/subagents/spawn/subagent-spawn.production-boundary.test.ts`, `src/agents/tools/dashboard-tool.test.ts`, `src/agents/tools/gateway.runtime-identity.test.ts`, `src/agents/tools/in-process-gateway.ts`, `src/auto-reply/reply/agent-runner-execution.ts`, `src/auto-reply/reply/agent-runner-run.ts`, `src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts`, `src/auto-reply/reply/commands-plugins.install-clawhub-spec.test.ts`, `src/auto-reply/reply/commands-plugins.ts`, `src/auto-reply/reply/commands-system-agent.ts`, `src/auto-reply/reply/dispatch-from-config.lifecycle.ts`, `src/auto-reply/reply/dispatch-from-config.reply-dispatch.test.ts`, `src/auto-reply/reply/followup-runner.test.ts`, `src/auto-reply/reply/followup-runner.ts`, `src/auto-reply/reply/reply-turn-admission.ts`, `src/canvas/widget-tool.ts`, `src/channels/plugins/registry-loader.ts`, `src/channels/plugins/registry.ts`, `src/cli/plugin-invocation-resources.owner.test.ts`, `src/cli/run-main.cleanup.test.ts`, `src/cron/trigger-script.preparation.test.ts`, `src/gateway/board-host-tools.ts`, `src/gateway/local-request-context.session-tools.test.ts`, `src/gateway/local-request-context.test.ts`, `src/gateway/local-request-context.ts`, `src/gateway/node-agent-cli-runtime.ts`, `src/gateway/node-claude-skill-runtime.test.ts`, `src/gateway/node-claude-skill-runtime.ts`, `src/gateway/node-invoke-plugin-policy.session-full.test.ts`, `src/gateway/node-invoke-plugin-policy.ts`, `src/gateway/operator-approval-placement-grants.test.ts`, `src/gateway/server-cron.test.ts`, `src/gateway/server-in-process-execution-lifetime.test.ts`, `src/gateway/server-methods.ts`, `src/gateway/server-methods/board.runtime-boundaries.test.ts`, `src/gateway/server-methods/hooks-status.ts`, `src/gateway/server-methods/plugins.runtime-owner.test.ts`, `src/gateway/server-methods/session-catalog-privacy.test.ts`, `src/gateway/server-methods/session-catalog-provider-access.test.ts`, `src/gateway/server-methods/session-catalog-provider-access.ts`, `src/gateway/server-methods/session-catalog.ts`, `src/gateway/server-methods/sessions-rewind.test.ts`, `src/gateway/server-methods/web.ts`, `src/gateway/server-plugin-in-process-dispatch.authorization.test.ts`, `src/gateway/server-plugin-in-process-dispatch.ts`, `src/gateway/server-plugin-reload.memory.test-support.ts`, `src/gateway/server-plugin-subagent-runtime.test.ts`, `src/gateway/server-plugin-subagent-runtime.ts`, `src/gateway/server-plugins-node-runtime.ts`, `src/gateway/server-plugins.lifecycle.channels.test.ts`, `src/gateway/server-plugins.subagent-ended-hook.test.ts`, `src/gateway/server-plugins.test.ts`, `src/gateway/server-plugins.ts`, `src/gateway/server-runtime-services.test.ts`, `src/gateway/server-runtime-state.tailscale.test.ts`, `src/gateway/server-startup-plugins.test.ts`, `src/gateway/server-startup-post-attach.test.ts`, `src/gateway/server.cron.test.ts`, `src/gateway/server.plugin-frame-auth.test.ts`, `src/gateway/server.plugin-http-auth.test.ts`, `src/gateway/server.plugin-http-role-scopes.test.ts`, `src/gateway/server/hooks.agent-trust.test.ts`, `src/gateway/server/plugins-http.ownership.test.ts`, `src/gateway/server/plugins-http.test.ts`, `src/gateway/session-worker-placement-context.ts`, `src/gateway/tool-resolution.terminal.test.ts`, `src/gateway/tools-invoke-http.test.ts`, `src/gateway/worker-environments/worker-turn-launcher-computer.test.ts`, `src/gateway/worker-environments/workspace-result-finalize.ts`, `src/infra/outbound/channel-bootstrap.runtime.ts`, `src/infra/outbound/channel-resolution.ts`, `src/infra/outbound/deliver-channel.ts`, `src/infra/outbound/runtime-visible-channels.ts`, `src/node-host/plugin-node-host.test.ts`, `src/plugin-sdk/agent-harness-task-runtime.test.ts`, `src/plugin-sdk/facade-activation-check.runtime.ts`, `src/plugin-sdk/gateway-method-runtime.test.ts`, `src/plugin-sdk/gateway-method-runtime.ts`, `src/plugin-sdk/plugin-runtime.ts`, `src/plugin-sdk/provider-catalog-runtime.test.ts`, `src/plugin-sdk/webhook-ingress.test.ts`, `src/plugin-sdk/webhook-ingress.ts`, `src/plugins/capability-provider-runtime.ts`, `src/plugins/cli-gateway-nodes-runtime.ts`, `src/plugins/compaction-provider.test.ts`, `src/plugins/current-plugin-metadata-snapshot.test.ts`, `src/plugins/hook-runner-global-state.ts`, `src/plugins/legacy-sdk-resource-host.ts`, `src/plugins/memory-runtime.owners.test.ts`, `src/plugins/memory-runtime.test.ts`, `src/plugins/migration-provider-runtime.test.ts`, `src/plugins/plugin-command-registry.ts`, `src/plugins/plugin-instance-callbacks.test.ts`, `src/plugins/plugin-instance.test.ts`, `src/plugins/plugin-module-loader-cache.ts`, `src/plugins/provider-registry-selection.ts`, `src/plugins/providers.runtime-core.ts`, `src/plugins/public-surface-generation.test.ts`, `src/plugins/registry-lifecycle.test.ts`, `src/plugins/registry-runtime.hooks.test.ts`, `src/plugins/registry.runtime-config.test.ts`, `src/plugins/registry.runtime-session-ownership.test.ts`, `src/plugins/runtime-context.test.ts`, `src/plugins/runtime-context.ts`, `src/plugins/runtime/gateway-request-scope.test-fixtures.ts`, `src/plugins/runtime/gateway-request-scope.test.ts`, `src/plugins/runtime/runtime-agent.ts`, `src/plugins/runtime/runtime-embedded-agent.runtime.ts`, `src/plugins/runtime/runtime-llm.runtime.ts`, `src/plugins/runtime/runtime-web-channel-plugin.test.ts`, `src/plugins/services.return-contract.test.ts`, `src/plugins/tools.optional.test.ts`, `src/plugins/widget-presenters.ts`, `src/sessions/session-initialization.ts`, `src/sessions/session-lifecycle-admission.ts`, `src/system-agent/setup-inference-turn.test.ts`, `src/transcripts/status.test.ts`.

- **Registration/docs supplement:** `extensions/nostr/index.ts` uses `loadBundledEntryExportSync` with the `createNostrProfileHttpHandler` export in `api.ts`; its gateway-auth route is not a typed call edge. Existing registrations in `extensions/diagnostics-prometheus/index.ts` and `extensions/team-reports/index.ts` remain read-only. `docs/plugins/sdk-channel-plugins.md` records the callback, response-first 401, response expiry, and later independent-mutation rule.

- **Resolution limits:** Candidate resolved 89 of 180 project-position queries; BASE resolved 53 of 108. The 91/55 unresolved pairs are named in evidence: isolated plugin configs do not load core declarations, core does not load plugin entry declarations, and unrelated plugin configs do not load one another. Root and test resolve every position on each side. There are 132 independently unqueried configs per side; config parsing accounts for each by name and exact source-root membership. All returned reader files belong to selected roots. Only `tsconfig.scripts.json` has roots outside selected projects (754 candidate / 753 BASE); these received lexical search, not compiler reference queries. `extensions/tsconfig.package-boundary.base.json` is a no-input template and reports that parse diagnostic. Beam has no independent tsconfig. No zero-consumer claim is made for unresolved or unqueried project resolutions.

- **Evidence boundary:** Every tracked source/symlink matches its named Git tree during and after the census. The exhaustive raw records, declaration absences, projects, file groups and hashes are retained in private `revalidate-census-*` evidence. That historical census prepared 64 positions across 15 files and six projects for integration; its completed integration and the final supplements retain their separate identities below.


The retained eac0 integration census ran against merge `bb8a61bda6a50f41a3c3869f90e0344ca06f61d6`, tree `e67790db8eccc4315a16a0a08ae1504ff4e29dfc`, after pushed head `eac0c373fe17aeeda4f835810cbf2c71ebded124` was verified. The full union used 64 positions across 15 unchanged declaration files and six explicit projects. It returned 2,390 records / 1,005 exact reader groups across 211 files, with exit 0 and no ambiguous queries or tool failures. Root and test each resolved all 64 positions.

- All 194 files in the preceding correction census remain covered. The full union also names these 17 already-known auth/UI consumers: `src/gateway/control-ui-plugin-assets.ts`, `src/gateway/control-ui.ts`, `src/gateway/http-auth-utils.test.ts`, `src/gateway/http-endpoint-helpers.test.ts`, `src/gateway/http-utils.request-context.test.ts`, `src/gateway/plugin-icon-http.ts`, `src/gateway/server/plugin-route-runtime-scopes.test.ts`, `src/gateway/server/plugins-http.suspension-admission.test.ts`, `src/gateway/user-profiles-http.ts`, `ui/src/app/control-ui-auth.ts`, `ui/src/components/browser/browser-panel-download.test.ts`, `ui/src/components/browser/browser-panel-download.ts`, `ui/src/components/browser/browser-panel-native.test.ts`, `ui/src/components/browser/browser-panel-render.ts`, `ui/src/pages/channels/channels-page.ts`, `ui/src/pages/channels/nostr-profile-ops.test.ts`, `ui/src/pages/channels/nostr-profile-ops.ts`. The read-admission helpers preserve the Control UI/icon/assets/profile callers; the UI decoder and Nostr adapter retain their status/error, Save/Import and Browser callback flows. Complete per-file dispositions remain in the final evidence.

- Every structural reader delta was reviewed: 37 added and 37 removed identities are source-line moves. Of these, 36 come from earlier correction files; the merge-specific move is `src/plugins/plugin-module-loader-cache.ts:652→662`, whose active-request registry check is unchanged. The comparison explicitly uses 30 current-head query sets, 19 lint-correction sets and 15 earlier integration sets; it is not a direct full-union candidate query. No new behavior consumer was found in this final union.

- Core resolved 35/64; Nostr 4/64; Admin and Geolocation 1/64 each. The remaining 215 project-position pairs are explicit source/project-boundary gaps. All 132 skipped configs are separately named and parsed for membership. All returned reader files belong to selected roots; only `tsconfig.scripts.json` adds outside roots (754), with lexical rather than typed coverage. The package-boundary template retains its no-input parse diagnostic. Config files and lockfile are unchanged. These limits do not imply zero consumers.

- All 20 authored source/test/docs files are byte-identical between pushed head and merge. The assertion baseline separately incorporates an upstream `sdk-alias` allowance reduction from 3 to 2. Stable head and merge archives matched all 41,548 / 41,550 tracked entries before and after queries. This is source-reference evidence for eac0, not a replacement for runtime tests or CI.


CI type-repair census is bound to candidate `2d7774c389cdf2327391b5d1713e10e08a704575`, tree `fec9b073599495339d5b83b7d5696f3dc6757a75`. Ten declarations cover the four aliases, four changed public signatures and two directly referenced producers. Root/test/core all resolved: 30 candidate queries returned 310 reference records / 123 groups. Original BASE `3b88500581` received 27 new queries returning 280 records; three exact earlier plugin-authorizer queries (six records) were retained, for 115 BASE groups. No unresolved query, ambiguity or tool failure occurred.

- The existing 211-file consumer union remains required. The supplement names 13 further files: `src/commands/configure.gateway.test.ts`, `src/gateway/auth.test.ts`, `src/gateway/auth.ts`, `src/gateway/github-user-identity.cache.test.ts`, `src/gateway/http-auth-user-profile.ts`, `src/gateway/http-utils.authorize-request.test.ts`, `src/gateway/managed-image-attachments.ts`, `src/gateway/server-http-probes.ts`, `src/gateway/server/plugin-node-capability-auth.ts`, `src/gateway/server/ws-connection/auth-context.ts`, `src/gateway/session-kill-http.ts`, `src/gateway/tools-invoke-http.ts`, `src/gateway/user-profiles-http.auth.test.ts`. Complete combined coverage lists all 224 files in evidence. General HTTP/scoped/check callers keep their existing authorization policy; producer readers keep the same profile and connection contracts; new alias reads are type-only.

- Every original-BASE structural delta (35 added / 27 removed identities) has a source disposition. This comparison includes the earlier functional repair; it does not imply runtime changes in this CI patch. Native review verified exact signature equivalence and unchanged executable production behavior; earlier runtime proof retains its own eac0 identity.

- All 135 skipped configs per side remain named and membership-accounted. Every supplemental reader belongs to the selected source roots. Unqueried project resolution and native/dynamic consumers are not certified; exact-name apps/docs/scripts searches returned no matches. The final merge supplement below completes integration of these changed types.


Queue/persistence correction is source-reviewed and census-bound to `7285ad188c241ed9a51f9646967d1a2ba9070539`, tree `297a066691af763caf620a5d058e8b529cf73420`. The prior post-body check was too early: queued publication could start after revocation, and a later config save could follow revocation during relay I/O. PUT now revalidates inside its queued callback before publication and again before later config persistence; the response guard preserves HTTP 401. The new packaged red evidence reproduces both gaps through actual registration, public device revocation and held relay acknowledgements; its original package identity remains separate from final green evidence.

- Eight candidate declarations were queried in root/test/Nostr: 24 queries, 23 resolved, 93 references / 39 exact groups. Root/test resolve every declaration. The explicit unresolved cell is the core request-scope property in standalone Nostr; all seven Nostr declarations resolve there. Original BASE has 15 fresh plus six exact reused queries, all resolved, 73 references / 29 groups. No ambiguity or tool failure occurred.
- Every group and structural delta (15 added / five removed / 24 matched) has a source disposition. All 135 skipped configs per side remain named and membership-accounted. Historical evidence retains its original identities. The retained union now lists 228 typed/manual files: previous 224 plus `extensions/nostr/src/channel.ts`, `extensions/nostr/index.ts`, `src/plugin-sdk/keyed-async-queue.ts`, and `docs/plugins/sdk-channel-plugins.md`. The string-loaded registration is a manual/runtime contract, not a claim of typed resolution.
- Full candidate/BASE snapshots match before and after queries. Seven production callback sites serve four handlers/five effect branches. The check admits work about to start; an already-published relay event remains a fact when later config persistence is rejected. Final packaged green is bound to `7285ad18`; final postpush integration retains its own evidence and identity.

Final source integration is bound to actual merge `7ef62a14187cac6e4b2d731b5aa27459ddc300db`, tree `c96aedcf4f18b17d2fec7d79f9b14ef60498c3dd`, for pushed candidate `7285ad188c241ed9a51f9646967d1a2ba9070539`. Canonical census passed on this merge with comparator `93a5d82275`.

- The 18 changed-type/queue declarations received 72 actual-merge queries in root/test/core/Nostr: 54 resolved, 405 references / 162 exact groups across 34 files. Root/test resolve all 18 each; core resolves 11 and Nostr seven. The 18 unresolved cells are explicit cross-project source-boundary gaps, with no ambiguity or tool failure. The root comparison has zero added / zero removed / 162 matched identities, retaining ten prior CI query identities plus eight exact current queue identities.
- All 228 retained typed/manual paths have current merge bindings and dispositions. Two contain inherited source changes: the loader exactly matches the previously reviewed `bb8a61` blob and preserves its registry guard at line 662; isolated-completion tests add three expected callback arguments, while their existing dynamic registry read shifts 654→657 with the same meaning. No further affected query needed expansion. Historical full-census records retain their original identities; this is an actual-merge supplement, not a new full 64-position query.
- All 20 authored source/test/docs files are identical from pushed candidate to merge. The assertion baseline separately inherits `session-cost-usage-reporting.ts` 8→5 and `sdk-alias.ts` 3→2. Full candidate/merge snapshots match before and after queries: 41,548 / 41,561 tracked files. All 134 skipped configs are named and membership-accounted; dynamic registration still uses manual and packaged proof. Final package/runtime results retain candidate `7285ad1` and the explicit fresh-marker Import limitation from their own report.

## Invalidation

Each HTTP request rereads pairing state and verifies the current token, scopes, revocation, and issuer generation. The verifier checks the entire observed scope grant, so narrowing between lookup and verification cannot authorize the broader snapshot. Each effect checkpoint retains the original bearer and required scopes, reads current Gateway auth, and requires fresh device verification; a different successful auth method cannot replace the admitted device grant. The capability expires when its HTTP response closes. No credential cache is introduced. External operations already started are not cancelled by this checkpoint.

Real requests confirmed rotation and revocation take effect, forged admin headers fail, auth-generation changes reject old tokens, rate locks expire, and cross-origin/site mutations remain denied. The exact lookup-to-verification race is source-reviewed rather than forced by a runtime failpoint.

Each UI operation captures its connection/form/tab ownership and resolves current credentials. Existing cancellation, deadline, and generation checks suppress stale completion. The shared decoder has no cache; body decoding preserves aborts. Named-role policy and auth-bypass cache lifecycle are unchanged.

## Contention

Existing per-client credential serialization groups shared/device verification and failure accounting into one terminal attempt. No new queue or transaction is introduced. Eight concurrent invalid plugin requests under a three-failure limit yielded three 401 and five 429 responses. A valid device worked while only the shared-secret bucket was locked, was denied during the device lock, and worked after expiry. No limiter bypass or deadline reset was added. The new awaited checkpoint was exercised with body-pending revocation in real Nostr and Beam requests; neither blocked the independent public revoke command, and both rejected before their effect. Save now revalidates inside the existing queued callback, after the prior publication settles, and again before its later config write. The check cannot undo a relay publication already sent. Final packaged evidence confirms queued revocation prevents a second publication/config mutation and revocation during relay acknowledgement prevents the later config write. Public device revocation completed while requests waited; normal first publication completed successfully. No queue, relay timeout, or locking policy changed.

## Tests

- `src/gateway/http-auth-utils.paired-device.test.ts:23`: registered `createGatewayHttpServer` plugin PUT/POST; current admin works, reader cannot forge admin, revoked/wrong credentials receive the Gateway 401 envelope. Regression fails on base and passes on candidate.
- `http-utils.authorize-request.test.ts`: removed the impossible generic-auth device-success mock. Generic HTTP admission is unchanged; registered plugin PUT/POST tests retain device authority and forged-header denial, including revocation with a pending body. Existing generic role/profile cases remain.
- `channels-page.test.ts`: registered `openclaw-channels-page` Save & Publish and Import; structured 401/403, non-JSON 503, two-credential recovery, and visible HTTP 400 validation details. Final Channels suite: 35 passed; focused Channels/Nostr/Browser set: 96 passed.
- `browser-panel-toolbar.test.ts`: registered `openclaw-browser-panel` Download renders HTTP 401 and Unauthorized; sibling download/native suites retain their existing coverage.
- `nostr-profile-ops.test.ts`: retained deadlines and stale/cancellation coverage. Deleted "preserves successful JSON responses for PUT and import" and "preserves the response when an error body is not JSON": internal return-shape assertions retired; registered rendered Channels success and non-JSON failure cases at `ui/src/pages/channels/channels-page.test.ts:235` replace them. One obsolete assertion allowance was removed; none added.
- Revalidation correction: 26 core tests across three files and 87 plugin/sibling tests across five files passed. The registered regression fails with the prior auth owner and passes with this candidate.
- Queue correction: 32 existing Nostr HTTP tests and 14 Beam sibling tests passed, plus focused lint/format. The first command chose a suite excluding Nostr and an incorrect Beam path, so no tests ran; the corrected suite/path passed. No test was edited or deleted in this correction. Its new regression uses the actual packaged Gateway registration.
- Targeted HTTP and UI suites, formatting, line limits, assertion ratchet, localization verification, and diff whitespace checks passed. Full type-aware lint, unused exports, and integration lanes remain CI-owned.

Production code grew to consolidate credential verification, transport verified authority, and decode errors at the shared boundary. The four-file/120-line guide was exceeded: 21 files, 529 written lines including tests, 242 removed lines.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-12 19:06:42 +05:30