Files
tech-log-frontend/docs/operations/adapter-remediation-ledger.md
T
DongHyeonkaandClaude Opus 5 bdee07a93b chore: sync the frontend template from a0fbafb to 5434760
Carries eight template commits: the provider sandbox actually running, release
admission to a named environment, the product feature manifest with its runtime
kill switch, architecture and documentation rules that match what is enforced,
the removability fixtures, and the browser, visual and performance evidence.

Product identity is unchanged. `package.json` keeps `tech-log-frontend` and the
catalog keeps the Tech Log naming; the home page was not in the delta. The
visual baselines are this product's own — the template's were excluded from the
transplant and these were regenerated here, where the only difference is the
platform overview's new product-feature section.

What this repository gains operationally: `config/runtime/{local,development,
staging,production}.json` with `FE-GATE-027` refusing an artifact whose runtime
document does not match the environment it is being admitted to, and
`FEATURE_OVERRIDES` for taking an installed feature out of service without a
rebuild.

Verified here: eight gates green, build green, visual 5/5, and 1,858 of 1,859
tests in the suites that do not need a sandbox — the one failure passes in
isolation and is a jsdom lazy-chunk timeout under parallel load. The provider
suites cannot run on this machine at all: `kernel.apparmor_restrict_unprivileged
_userns=1` makes `bwrap --unshare-net` fail, reproducible without any code from
either repository.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 21:34:19 +09:00

568 lines
64 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Adapter Remediation Ledger
> Source of truth for the execution state of every confirmed finding in
> [`docs/reviews/adapters/`](../reviews/adapters/README.md).
>
> Plan: [2026-08-13 adapter remediation](../superpowers/plans/2026-08-13-adapter-remediation.md).
> Baseline revision: `develop` / `4dc033cf33a5b6173bbf960d5eb464a406dc4c92`.
## Containment state (plan Task 1, Step 1)
Scan performed on the baseline revision:
```bash
rg -n "createBrowserOpfsRuntime|createBrowserFileRuntime|createPublicResponseCache|createBrowserRpcRuntime|createWebPush|createServiceWorker|createResumableUpload|createImageCdn" src recipes tests
rg -n "AVAILABLE_NOT_COMPOSED|DESIGNED_NOT_IMPLEMENTED|NOT_SELECTED" docs/architecture src/bootstrap
```
Result:
| Capability | Template default composition | Containment action |
| --- | --- | --- |
| OPFS byte store (`createBrowserOpfsRuntime`) | Not composed. Only `recipes/frontend-capabilities/*` reference the `"OPFS"` backend literal in contract/fake code. | None required. No V1 writer is admitted, so no kill switch is invented. |
| Browser files runtime | Not composed in `src/bootstrap/**`. | None. |
| Public response cache | Not composed; only `tests/unit/public-response-cache.test.ts` constructs it. | None. |
| Browser RPC runtime | Not composed; `AVAILABLE_NOT_COMPOSED`. | None. |
| Web Push | Not composed; `NOT_SELECTED` / `AVAILABLE_NOT_COMPOSED`. | None. |
| Resumable upload / image CDN | Not composed; test-only construction. | None. |
| Service Worker runtime host | Composed conditionally through `src/bootstrap/optional-runtime-host.ts``createServiceWorkerRuntimeHost`, gated by `ResolvedRuntimeCapabilities`. | Stays as-is. Task 14 fixes truthfulness without changing selection. |
| Realtime | `src/bootstrap/optional-runtime-host.ts:91` keeps realtime `NOT_SELECTED` with `realtime: null`. | None. |
No product-specific composition root outside the template default exists in this repository, so
there is no OPFS V1 write admission to close.
## Baseline gates (plan Task 1, Step 3)
Captured on the baseline revision before any source change.
| Command | Exit code | Result |
| --- | ---: | --- |
| `corepack pnpm check:types` | 0 | app, node, test, recipes, web-worker, service-worker projects all pass. |
| `corepack pnpm lint` | 0 | `--max-warnings=0` clean. |
| `corepack pnpm check:architecture` | 0 | 286 modules, 854 dependencies, all imports resolved; 12 graph fixtures PASS; TS-only policy PASS; allowed PASS / 9 forbidden rejected. |
| `corepack pnpm test:unit` | 1 | 110 passed / 1 failed test files; 1496 passed / 19 failed tests (1515 total), 150.92s. |
### `test:unit` failure attribution
The single failing file is `tests/unit/ci-artifact-contract.test.ts`. All 19 failures come from
child-process, cgroup, and filesystem-permission behavior of the sandboxed execution
environment, not from adapter code. Verbatim causes recorded from the run log:
```
Error: ENOENT: no such file or directory, open '/proc/1325422/task/1325422/children'
Error: provider output did not reach expected content: /tmp/ci-provider-upload-J9hxXD/provider-evidence/untrusted/vulnerability-report.json
Error: provider scope survived completion: ca-provider-vulnerability-1326812-f4869853ef09ea2c2c95cd01.scope
Error: EACCES: permission denied, open '/tmp/ci-captured-archive-OWTs7M/candidate.tar.gz'
Error: Test timed out in 10000ms.
AssertionError: expected 5714 to be less than 5000
AssertionError: expected [] to deeply equal ArrayContaining{…}
```
This matches the environment note already recorded in the review index. It is **not** converted
to an adapter failure and it is **not** treated as green. Every adapter task below must keep the
adapter-focused suites green and must not increase this file's failure count.
## Finding ledger
`Activation` records whether the finding is reachable on the current template execution path.
Rollout state starts at `NOT_STARTED`; documented-unimplemented items start at
`PROMOTION_BLOCKED` and are never labelled `DEFECT`.
### Network and state (`docs/reviews/adapters/01-network-and-state.md`)
| ID | Activation | Red test command | Fix commit/PR | Rollout state | Rollback trigger | Evidence |
| --- | --- | --- | --- | --- | --- | --- |
| N-01 | Live V3 path | `corepack pnpm exec vitest run tests/integration/http-execution-v3-observability.test.ts` | `fix: restore V3 HTTP observability` | `FIXED_NOT_RELEASED` | diagnostics/telemetry producer gate regression | Red 5/5 failed → green 5/5; `check:diagnostics` PASS (8 diagnostics, 5 telemetry producers); `check:types` PASS; `check:architecture` PASS |
| N-02 | Live V3 path | `corepack pnpm exec vitest run tests/integration/http-execution-v3-auth-profile.test.ts` | `fix: enforce installed HTTP auth profiles` | `FIXED_NOT_RELEASED` | authenticated request 4xx spike after profile enforcement | Red suite failed to load (`installRestAuthProfileRegistry` absent) → green 7/7; `check:types` PASS; `check:architecture` PASS; `lint` PASS; unit+integration+features 1560 passed with only the pre-existing environmental `ci-artifact-contract` failures |
| N-03 | Live V3 path | `corepack pnpm exec vitest run tests/unit/http-execution-v3.test.ts -t "retry-time fence"` | `fix: preserve command effect certainty across retries` | `FIXED_NOT_RELEASED` | command effect verdict regression | Red reproduced `SCOPE_FENCED` with `NOT_STARTED` after one dispatched attempt → green `MAYBE_APPLIED`; lattice table 9/9; `check:types` PASS; `lint` PASS |
| N-04 | Live composition teardown | `corepack pnpm exec vitest run tests/unit/telemetry.test.ts tests/unit/runtime-adapters.test.ts` | `fix: terminate telemetry work on disposal` | `FIXED_NOT_RELEASED` | telemetry delivery loss after teardown change | Red 10 failed (5 lifecycle + 5 capacity) → green 34/34; `check:diagnostics` PASS; `check:types` PASS; `check:architecture` PASS; `lint` PASS |
| N-05 | Rollout blocker (sidecar not composed) | `corepack pnpm exec vitest run tests/unit/conditional-validator-store.test.ts` | `fix: harden bounded state sidecars` | `FIXED_NOT_RELEASED` | persisted validator key incompatibility | Red collision case (two valid bindings sharing one delimiter-joined key) → green; key is now a bounded validated tuple encoded with `JSON.stringify` |
| N-06 | Legacy V2 rollback seam | `corepack pnpm exec vitest run tests/integration/http-client.test.ts` | `fix: harden the legacy HTTP rollback path` | `FIXED_NOT_RELEASED` | legacy keyed command rejection spike | Red 4 invalid-key cases → green; rejection happens before credentials and fetch (0 credential calls, 0 fetches) |
| N-07 | Legacy V2 rollback seam | `corepack pnpm exec vitest run tests/integration/http-client.test.ts tests/integration/auth-recovery.test.ts` | `fix: harden the legacy HTTP rollback path` | `FIXED_NOT_RELEASED` | legacy credential timeout regression | Red never-settling owner → green; credential wait races the existing attempt controller so no extra timer is added; ownership maps to REQUEST_TIMEOUT / REQUEST_ABORTED / AUTH_INTEGRATION_FAILURE with zero fetches |
| N-08 | Legacy V2 rollback seam | `corepack pnpm exec vitest run tests/unit/bounded-json-compatibility.test.ts` | `fix: harden the legacy HTTP rollback path` | `FIXED_NOT_RELEASED` | legacy JSON failure-code drift | Green 7/7 including throwing cancel/releaseLock; `readBoundedJson` now delegates to `bounded-body-reader` with the legacy codes preserved |
| N-09 | Live cross-context host | `corepack pnpm exec vitest run tests/unit/cross-tab-invalidation.test.ts` | `fix: harden bounded state sidecars` | `FIXED_NOT_RELEASED` | cross-tab invalidation drop | Red foreign-area pulse accepted → green 13/13; localStorage captured once and `StorageEvent.storageArea` compared by object identity; pulse key registered as `CACHE_INVALIDATION_PULSE`; `check:registries` PASS |
| N-10 | Cursor runtime `AVAILABLE_NOT_COMPOSED` | `corepack pnpm exec vitest run tests/unit/cursor-pagination-runtime.test.ts` | `fix: harden bounded state sidecars` | `FIXED_NOT_RELEASED` | pagination abort semantics change | Red never-settling loader → green `PAGINATION_ABORTED` with the late page ignored |
| N-11 | Live composition | `corepack pnpm exec vitest run tests/unit/telemetry.test.ts -t capacity` | `fix: terminate telemetry work on disposal` | `FIXED_NOT_RELEASED` | capacity rejection on valid composition | Red 5/5 capacity cases → green; ceilings documented in VD-07 §7-4 |
### Storage and browser files (`docs/reviews/adapters/03-storage-and-browser-files.md`)
| ID | Activation | Red test command | Fix commit/PR | Rollout state | Rollback trigger | Evidence |
| --- | --- | --- | --- | --- | --- | --- |
| STO-01 | OPFS not composed in template; **Critical** for any product writer | `corepack pnpm exec vitest run tests/unit/opfs-byte-store.test.ts tests/unit/opfs-worker-runtime.test.ts tests/unit/indexeddb-opfs-journal.test.ts` | `fix: preserve OPFS recovery authority during cleanup` | `FIXED_NOT_RELEASED` | OPFS reconcile backlog or journal growth | Red 4 new saga cases → green 25/25 across the three OPFS suites; `check:types` PASS (incl. web-worker); `check:browser-file-storage-boundaries` PASS; `lint` PASS; `test:unit` 1511 passed with only the pre-existing environmental `ci-artifact-contract` failures |
| STO-02 | Browser file runtime not composed | `corepack pnpm exec vitest run tests/unit/browser-file-download.test.ts` | `fix: execute canonical browser download targets` | `FIXED_NOT_RELEASED` | download navigation blocked by canonical target | Red 2 failed (raw relative href handed to host) → green 17/17 |
| STO-03 | Public cache not composed | `corepack pnpm exec vitest run tests/unit/public-response-cache.test.ts` | `fix: make public cache staging repairable` | `FIXED_NOT_RELEASED` | composition rejection of an existing policy | Red 4 cases across STO-03..05 → green 21/21; `check:types` PASS; `check:browser-file-storage-boundaries` PASS; `lint` PASS |
| STO-04 | Public cache not composed | `corepack pnpm exec vitest run tests/unit/public-response-cache.test.ts` | `fix: make public cache staging repairable` | `FIXED_NOT_RELEASED` | restage loop or bandwidth spike | — |
| STO-05 | Public cache not composed | `corepack pnpm exec vitest run tests/unit/public-response-cache.test.ts` | `fix: make public cache staging repairable` | `FIXED_NOT_RELEASED` | activation permitted without required capability | — |
| STO-06 | IndexedDB maintenance | `corepack pnpm exec vitest run tests/unit/indexeddb-maintenance.test.ts` | `fix: bound migration commits and version the OPFS worker protocol` | `FIXED_NOT_RELEASED` | migration checkpoint stall | Red commit-phase deadline case → green 13/13; the monotonic budget is re-checked before each record's first write, a started record still finishes atomically, and a clock failure aborts the transaction |
| STO-07 | OPFS worker protocol | `corepack pnpm exec vitest run tests/unit/opfs-worker-runtime.test.ts` | `fix: bound migration commits and version the OPFS worker protocol` | `FIXED_NOT_RELEASED` | page/worker `INCOMPATIBLE` spike | Green 23/23 across the OPFS suites; every envelope carries `OPFS_WORKER_PROTOCOL_VERSION = 2` and the response echoes its request kind, with a strict failure-shape decoder. A kind or version mismatch closes as `UNSUPPORTED` — the closed taxonomy has no `INCOMPATIBLE` code and none was invented |
| STO-08 | Hypothesis; browser characterization required | `corepack pnpm exec playwright test --config playwright.capabilities.config.ts tests/browser-capabilities/browser-files.spec.ts` | none (source unchanged) | `UNVERIFIED` | n/a until characterized | chromium 2/2 PASS; webkit could not launch (`libevent-2.1-7t64`, `libavif16` missing — environmental). The existing spec does not exercise `Window.showOpenFilePicker`/`showSaveFilePicker`, which need a user gesture and a native dialog, so the receiver-binding hypothesis is **neither reproduced nor refuted**. No `SystemPickerHost` was introduced: the plan forbids implementing an uncharacterized hypothesis as a defect. |
| GAP-01 | Documented unimplemented (VD-15) | promotion evidence, not a red test | — | `PROMOTION_BLOCKED` | n/a | — |
| GAP-02 | Documented unimplemented (VD-15) | promotion evidence, not a red test | — | `PROMOTION_BLOCKED` | n/a | — |
| GAP-03 | Documented unimplemented (VD-15) | promotion evidence, not a red test | — | `PROMOTION_BLOCKED` | n/a | — |
### Realtime and Browser RPC (`docs/reviews/adapters/02-realtime-and-browser-rpc.md`)
| ID | Activation | Red test command | Fix commit/PR | Rollout state | Rollback trigger | Evidence |
| --- | --- | --- | --- | --- | --- | --- |
| R-01 | Browser RPC `AVAILABLE_NOT_COMPOSED` | `corepack pnpm exec vitest run tests/unit/browser-rpc/browser-rpc-runtime.test.ts` | `fix: install bounded Browser RPC stream leases` | `FIXED_NOT_RELEASED` | stream lease deadlock | Stream cleanup is bounded; the generator no longer waits indefinitely on a non-cooperative `iterator.return()` |
| R-02 | Realtime `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/realtime/stream-coordinator.test.ts` | `fix: retain realtime work through draining` | `FIXED_NOT_RELEASED` | stream stuck in `DRAINING` | Red never-settling effect and recovery → green 27/27; `close()` returns `IDLE_TIMEOUT` while a task is retained and success only after actual settlement |
| R-03 | Realtime `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/realtime/live-poll-handoff-coordinator.test.ts` | `fix: retain realtime work through draining` | `FIXED_NOT_RELEASED` | retired-writer set growth | Red overflow fail-close then `close()` → green 11/11; retired writers are waited on and only removed once actually quiesced |
| R-04 | Browser RPC `AVAILABLE_NOT_COMPOSED` | `corepack pnpm exec vitest run tests/unit/browser-rpc/browser-rpc-contract.test.ts` | `fix: install bounded Browser RPC stream leases` | `FIXED_NOT_RELEASED` | binding install rejection | Red post-validation mutation, accessor and symbol cases → green 19/19; getters are never invoked |
| R-05 | WebSocket protocol codec | `corepack pnpm exec vitest run tests/unit/realtime/websocket-protocol.test.ts` | `fix: install bounded Browser RPC stream leases` | `FIXED_NOT_RELEASED` | frame rejection regression | Red oversize frame allocated an encoder copy → green 8/8; byte counts match `TextEncoder` including lone surrogates |
| R-06 | Browser RPC `AVAILABLE_NOT_COMPOSED` | `corepack pnpm exec vitest run tests/unit/browser-rpc/browser-rpc-runtime.test.ts` | `fix: install bounded Browser RPC stream leases` | `FIXED_NOT_RELEASED` | closed-failure taxonomy drift | Clock and fence reads are canonicalised into the closed Result taxonomy with single-exit cleanup |
| R-07 | Promotion blocker | concrete transport conformance evidence | — | `PROMOTION_BLOCKED` | n/a | — |
### Browser transfer (`docs/reviews/adapters/04-browser-transfer.md`)
| ID | Activation | Red test command | Fix commit/PR | Rollout state | Rollback trigger | Evidence |
| --- | --- | --- | --- | --- | --- | --- |
| BT-PRE-01 | Presigned `AVAILABLE_NOT_COMPOSED` | `corepack pnpm exec vitest run tests/unit/presigned-transfer.test.ts` | `fix: lazy presigned download leases` | `FIXED_NOT_RELEASED` | download lease leak | Red lazy-lease cases → green 29/29; `open()` performs no network I/O and `close()` is idempotent |
| BT-PRE-02 | Wire contract gap | `corepack pnpm exec vitest run tests/unit/presigned-transfer.test.ts` | `fix: complete presigned capability and upload transport contracts` | `FIXED_NOT_RELEASED` | provider `POLICY_REJECTED` spike | Red missing/V0/V2 protocol cases → green; request always declares `PRESIGNED_TRANSFER_V1` and a mismatched response is closed as `POLICY_REJECTED` before vault registration |
| BT-PRE-03 | Presigned provider | `corepack pnpm exec vitest run tests/unit/presigned-transfer.test.ts` | `fix: complete presigned capability and upload transport contracts` | `FIXED_NOT_RELEASED` | timeout not bounding fetch | Red non-cooperative fetch → green; the scope races the task, the late response body is cancelled, and a throwing scheduler leaks no listener |
| BT-PRE-04 | Presigned vault | `corepack pnpm exec vitest run tests/unit/presigned-transfer.test.ts` | `fix: complete presigned capability and upload transport contracts` | `FIXED_NOT_RELEASED` | issuer/consumer split break | Red 6-case issuer-seam table → green; the vault re-checks method, href/origin/path agreement, credentials, byte, digest and expiry invariants itself |
| BT-PRE-05 | Provider path decoding | `corepack pnpm exec vitest run tests/unit/presigned-transfer.test.ts` | `fix: complete presigned capability and upload transport contracts` | `FIXED_NOT_RELEASED` | legitimate key rejection | Red `%2F`, `%5C`, `%252e%252e`, lowercase percent-hex and `%00` → green; each segment is decoded once and must round-trip through the canonical uppercase encoder |
| BT-UP-01 | Resumable transport | `corepack pnpm exec vitest run tests/unit/resumable-upload-fetch-transport.test.ts` | `fix: harden resumable upload transport contracts` | `FIXED_NOT_RELEASED` | signal facade rejection | `isAbortSignal` now requires `removeEventListener` and release cleanup is isolated |
| BT-UP-02 | Resumable transport | `corepack pnpm exec vitest run tests/unit/resumable-upload-fetch-transport.test.ts` | `fix: complete presigned capability and upload transport contracts` | `FIXED_NOT_RELEASED` | clock injection break | Clock and scheduler are injected and snapshotted; delta-seconds and HTTP-date both resolve against the same captured `now`, with clock rollback clamped to 0 |
| BT-UP-03 | Resumable checkpoint store | `corepack pnpm exec vitest run tests/unit/resumable-upload-checkpoint.test.ts` | `fix: report unknown IndexedDB delete effects` | `FIXED_NOT_RELEASED` | pending-delete registry growth | Red blocked-deadline case → green `PENDING`/`UNKNOWN`; a realm-scoped registry blocks recreating the partition |
| BT-UP-04 | Presigned part executor | `corepack pnpm exec vitest run tests/unit/resumable-upload-checkpoint.test.ts` | `fix: harden resumable upload transport contracts` | `FIXED_NOT_RELEASED` | expiry check rejection | Non-finite and negative clocks return `UNAVAILABLE`/`RESUME` instead of bypassing expiry |
| BT-UP-05 | Refactor | `corepack pnpm exec vitest run tests/unit/resumable-upload-runtime.test.ts` | — | `NOT_PERFORMED` | characterization drift | **Attempted and reverted.** The five internal owners were extracted mechanically, but they require a shared-internals module for `RuntimeDependencies`, `ActiveResolution`, `ReconciliationResolution`, `FAILURE_CODES`, `RECOVERIES`, `reportProgress`, `observeTerminal` and ~40 further bindings to avoid an import cycle. Rather than risk the verified correctness work in this file, the extraction was reverted rather than half-landed. Behaviour and the public facade are unchanged; the file is still 2,239 lines. |
| BT-UP-06 | Refactor | `corepack pnpm exec vitest run tests/unit/resumable-upload-runtime.test.ts` | `fix: drain resumable upload teardown` | `FIXED_NOT_RELEASED` | drain not quiescent | Red single-flight dispose case → green 18/18; `close()` closes admission and starts the same drain, `dispose()` aborts the active-operation registry and awaits real settlement before closing the checkpoint store |
| BT-UP-07 | Documented gap (Web Locks matrix) | promotion evidence | — | `PROMOTION_BLOCKED` | n/a | — |
| BT-IMG-01 | Type-contract change | `corepack pnpm check:types:test` fixture | `fix: complete presigned capability and upload transport contracts` | `FIXED_NOT_RELEASED` | caller compile break | `resolve()` now requires the lifetime signal; `tests/fixtures/typecheck/invalid-image-cdn-resolve-signal.ts` + `check:types:fixture:image-resolve-signal` fail as designed (2 errors), and all callers pass a signal |
| BT-IMG-02 | Image probe | `corepack pnpm exec vitest run tests/unit/image-cdn-runtime.test.ts` | `fix: parse Cache-Control with quote awareness` | `FIXED_NOT_RELEASED` | Cache-Control parse rejection | Red unmatched-quote cases → green 25/25 |
| BT-IMG-03 | Refactor | `corepack pnpm exec vitest run tests/unit/image-cdn-runtime.test.ts` | — | `NOT_PERFORMED` | characterization drift | **Not performed.** Same reasoning as BT-UP-05: a pure cohesion refactor of `image-cdn-runtime.ts` (1,340 lines) with no finding closure. `image-header-metadata.ts` is deliberately left intact per the review. |
| BT-IMG-04 | Documented gap (descriptor provider) | promotion evidence | — | `PROMOTION_BLOCKED` | n/a | — |
| BT-X-01 | Shared abort mechanics | `corepack pnpm exec vitest run tests/unit/abortable-operation.test.ts` | `fix: share abort and deadline mechanics` | `FIXED_NOT_RELEASED` | late-result compensation regression | Golden suite 8/8: first terminal owner, idempotent close, throwing scheduler, observed late rejection, late-handle compensation |
### Service Worker and Web Push (`docs/reviews/adapters/05-service-worker-and-web-push.md`)
| ID | Activation | Red test command | Fix commit/PR | Rollout state | Rollback trigger | Evidence |
| --- | --- | --- | --- | --- | --- | --- |
| SW-URL-01 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: make Service Worker cache and removal outcomes truthful` | `FIXED_NOT_RELEASED` | static asset cache miss rate | Red generator-shaped root-relative asset vs absolute Request URL → green; manifest URLs canonicalized once against the registration scope |
| SW-01 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: make Service Worker cache and removal outcomes truthful` | `FIXED_NOT_RELEASED` | stale response served | Red previous-cache hit → green network fallback; only the current release cache is opened, matched and deleted from |
| SW-02 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: make Service Worker cache and removal outcomes truthful` | `FIXED_NOT_RELEASED` | foreign cache deletion | Red prefix deletion of `ca-static-v1-not-owned` and longer suffixes → green exact `isOwnedStaticCacheName` only |
| SW-03 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: make Service Worker cache and removal outcomes truthful` | `FIXED_NOT_RELEASED` | false removal success | Red `unregister() === false` reported as UNREGISTERED → green FAILED |
| SW-04 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: make Service Worker cache and removal outcomes truthful` | `FIXED_NOT_RELEASED` | removal outcome misreport | Red removal modes always DISABLED → green outcome matrix (ABSENT/UNREGISTERED/PURGED→DISABLED, OWNERSHIP_MISMATCH→INCOMPATIBLE, FAILED→FAILED) |
| SW-05 | Build gate | `corepack pnpm exec vitest run tests/unit/service-worker-build-input.test.ts` | `fix: make Service Worker cache and removal outcomes truthful` | `FIXED_NOT_RELEASED` | build admission rejection | Red tamper table (stale digest, byte length, cross-origin URL, dot segment, extension mismatch, unknown field, duplicate URL) → green; build gate decodes through the shared codec and recomputes the canonical digest |
| SW-06 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: harden Service Worker activation and install lifecycle` | `FIXED_NOT_RELEASED` | activation handshake failure | Red foreign-source drain, source swap and 10 concurrent activations → green 24/24; replies correlate by source object identity against the captured waiting worker or controller, and activation/reset are single-flight |
| SW-07 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: harden Service Worker activation and install lifecycle` | `FIXED_NOT_RELEASED` | activation blocked with zero clients | An empty in-scope client set is vacuously drained; `clients.matchAll()` failure still rejects |
| SW-08 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: harden Service Worker activation and install lifecycle` | `FIXED_NOT_RELEASED` | per-client failure escalation | Per-client `postMessage` isolation; `skipWaiting()` is the commit point and its failure is REJECTED, with accepted/reload notifications sent only afterwards as best effort |
| SW-09 | Composed when capability selected | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | `fix: harden Service Worker activation and install lifecycle` | `FIXED_NOT_RELEASED` | late install work observed | Red late-fetch case → green; a fenced worker starts no new candidate work, late response bodies are cancelled, digest throws map to a closed outcome, and a second exact-delete runs once the abandoned install settles without extending the public bound |
| SW-10 | Protocol V2 migration | `corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts` | — | `DEFERRED_TO_MIGRATION` | V1/V2 mismatch fail-close | Not closed here. Full-identity protocol V2 is an expand → dual-read → old-writer drain → contract deployment that spans releases; the prerequisite shared manifest codec and canonical digest landed with SW-05. |
| WP-01 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-fence-store.test.ts` | `fix: bind Web Push mutations to exact authority` | `FIXED_NOT_RELEASED` | CAS receipt rejection | Red stale/skipped/huge revision receipts → green; write and remove share one exact-next-revision validator |
| WP-02 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-fence-store.test.ts` | — | `DEFERRED_TO_MIGRATION` | `RECONCILIATION_REQUIRED` backlog | Deferred to the Task 16 versioned-migration PR: `MUTATION_OUTCOME_UNKNOWN` and the `RECONCILIATION_REQUIRED` lifecycle are part of the same wire/data migration as WP-03. |
| WP-03 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-subscription-adapter.test.ts` | — | `DEFERRED_TO_MIGRATION` | backend receipt mismatch | Deferred to the Task 16 versioned-migration PR: the V2 receipt requires server request-shape negotiation before a client rollout. |
| WP-04 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-subscription-adapter.test.ts` | — | `DEFERRED_TO_MIGRATION` | reconcile loop | Deferred with WP-03: `expectedPreviousAssociationEpoch` and `replacedAssociationEpoch` are part of the V2 register contract. |
| WP-05 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-subscription-adapter.test.ts` | `fix: bind Web Push mutations to exact authority` | `FIXED_NOT_RELEASED` | pre-abort observation drift | A pre-aborted command records the requested operation instead of always INSPECT |
| WP-06 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-worker-runtime.test.ts` | `fix: bind Web Push mutations to exact authority` | `FIXED_NOT_RELEASED` | truncation reported degraded | Client handoff and notification cleanup report `countBucket` and `truncated`; an incomplete cleanup returns `{ complete: false }` and is DEGRADED |
| WP-07 | Web Push `NOT_SELECTED` | `corepack pnpm exec vitest run tests/unit/web-push-worker-runtime.test.ts` | `fix: bind Web Push mutations to exact authority` | `FIXED_NOT_RELEASED` | late native effect certainty | Native notification effect is tracked as NOT_APPLIED → MAYBE_APPLIED → CONFIRMED and observed as evidence only |
## Final evidence (plan Task 18)
Captured after every correctness task landed.
### Focused subsystem suites (fresh processes)
| Suite | Exit | Result |
| --- | ---: | --- |
| `tests/unit/browser-rpc` + `tests/unit/realtime` | 0 | 192 passed |
| OPFS, IndexedDB, public cache, download | 0 | 80 passed |
| abortable-operation, presigned, resumable, image CDN | 0 | 104 passed |
| Service Worker + Web Push | 0 | 66 passed |
### Repository gates
| Command | Exit | Result |
| --- | ---: | --- |
| `corepack pnpm check:types` | 0 | all six projects pass |
| `corepack pnpm lint` | 0 | `--max-warnings=0` clean |
| `corepack pnpm check:architecture` | 0 | 288 modules, 865 dependencies; 12 fixtures PASS; allowed PASS / 9 forbidden rejected |
| `corepack pnpm check:diagnostics` | 0 | 8 diagnostics and 5 telemetry producers PASS |
| `corepack pnpm check:browser-file-storage-boundaries` | 0 | PASS, 34 rejections |
| `corepack pnpm check:realtime-boundaries` | 0 | PASS |
| `git diff --check` | 0 | clean |
| `corepack pnpm test:component` | 0 | 126 passed |
| `corepack pnpm test:integration` | 0 | 52 passed |
| `corepack pnpm test:reference-feature` | 0 | 26 passed |
| `corepack pnpm test:recipes` | 0 | 17 passed |
| `corepack pnpm test:unit` | 1 | 1585 passed / 19 failed tests; the 19 are the unchanged pre-existing `ci-artifact-contract` sandbox failures |
| `corepack pnpm check:registries` | 0 | 11 registries PASS |
| `corepack pnpm verify:documentation` | 0 | PASS_SCOPED |
| `corepack pnpm check:types:fixture:image-resolve-signal` | 1 | **Expected non-zero.** Negative fixture proving `resolve()` now rejects a call without a lifetime signal (BT-IMG-01). |
`test:all` stops at `test:unit`, so the later suites above were run directly.
### Final disposition of all 64 findings
| State | Count |
| --- | ---: |
| `FIXED_NOT_RELEASED` | 51 |
| `PROMOTION_BLOCKED` (unchanged by design) | 6 |
| `DEFERRED_TO_MIGRATION` (`WP-02`, `WP-03`, `WP-04`, `SW-10`) | 4 |
| `NOT_PERFORMED` (`BT-UP-05`, `BT-IMG-03` cohesion refactors) | 2 |
| `UNVERIFIED` (`STO-08` browser hypothesis) | 1 |
No finding remains `NOT_STARTED`.
### Failures that are NOT claimed as green
| Gate | Status | Attribution |
| --- | --- | --- |
| `tests/unit/ci-artifact-contract.test.ts` | 19 failed | Identical to the baseline capture. Sandbox child-process, cgroup and `/tmp` permission behavior; unrelated to adapters. Count did not change across any task. |
| `corepack pnpm test:browser-capabilities` (webkit) | 6 failed / 24 passed | WebKit cannot launch: missing `libevent-2.1-7t64` and `libavif16`. Chromium passes. **UNVERIFIED**, not PASS. |
| `corepack pnpm test:browser-file-storage-removal` | exit 1 | The reduced-removal-fixture prunes the CI contract to 77/89/102 while `scripts/contracts/ci-gates.ts:481` demands exactly 81/93/105. That file, the CI contract and `scripts/lib/removal-fixture.ts` are **unchanged since the baseline revision** (`git diff --name-only 4dc033c..HEAD` outside `src/`, `tests/` and `docs/` lists only the two Service Worker build scripts), so this is pre-existing, not a regression from this work. |
| `corepack pnpm test:realtime-removal` | exit 1 | Same pre-existing reduced-fixture arithmetic. |
| Server/provider compatibility matrices (presigned V1, Web Push V1/V2, Service Worker V1/V2, OPFS V1/V2) | not run | No provider or multi-release infrastructure in this environment. **UNVERIFIED**. |
| Staging rollback drill | not run | Requires a staging deployment. **UNVERIFIED**. |
### Work deliberately not performed
| Plan task | Status | Reason |
| --- | --- | --- |
| Task 17 extraction (`BT-UP-05`, `BT-IMG-03`, OPFS/cache/download decomposition) | **NOT PERFORMED** | Pure cohesion refactor with no finding closure. `BT-UP-05` was attempted: the five internal owners extract cleanly, but they need a shared-internals module for ~40 types, constants and helpers to avoid an import cycle, so the attempt was reverted rather than half-landed. `BT-UP-06`, the one item in this group with behavioural content, **was** implemented. |
| `SW-10`, OPFS physical/protocol V2 rollout, presigned and Web Push receipt V2 (`WP-02`, `WP-03`, `WP-04`) | **DEFERRED_TO_MIGRATION** | These are expand → dual-read/emit → old-writer drain → contract deployments requiring server request-shape negotiation and multi-release drain windows. The prerequisite in-repo pieces landed: the shared Service Worker manifest codec and canonical digest (`SW-05`), the OPFS worker protocol version and strict correlation (`STO-07`), and the OPFS physical generation token (`STO-01`). |
| Promotion gaps `GAP-01`, `GAP-02`, `GAP-03`, `R-07`, `BT-UP-07`, `BT-IMG-04` | `PROMOTION_BLOCKED` | Unchanged by design. No availability state was raised and no optional capability was added to the default bootstrap. |
## Re-review remediation (2026-08-14)
Source: [`docs/reviews/adapters/RE-REVIEW-2026-08-14.md`](../reviews/adapters/RE-REVIEW-2026-08-14.md),
38 findings (High 19 / Medium 17 / Low 2) raised against `3b481eb`.
**GOV-02.** That re-review found the previous section of this ledger closed a
number of rows as `FIXED_NOT_RELEASED` that were in fact partial. The tables
below are written the other way round: a row is `FIXED` only where a new
adversarial test failed first on the pre-fix source and passes on the landed
one.
**All 38 second re-review findings are `FIXED` as scoped below.** The first pass
closed 26; the second closed the remaining twelve, which each needed a lifecycle
or contract change rather than a contained edit. A third re-review then found
that twenty of those closures held only on the paths their tests exercised; that
verdict and its remediation are recorded in the third re-review section further
down, and this section is left as written so the two passes stay comparable.
### Landed
| ID | Severity | Disposition | Commit | Red-then-green evidence |
| --- | --- | --- | --- | --- |
| LIVE-01 | High | `FIXED` | `f4bfdf0` | `tests/integration/http-execution-v3-live-authority.test.ts` — UNAVAILABLE, sync throw, async rejection and a malformed outcome each closed as `UNAUTHENTICATED` before the fix; all four now close as `AUTH_INTEGRATION_FAILURE` with zero fetches. |
| LIVE-02 | High | `FIXED` | `f4bfdf0` | `tests/unit/contract-registry-immutability.test.ts` — a borrowed `Map.prototype.clear` emptied the installed profile registry before the fix. |
| LIVE-03 | High | `FIXED` | `f4bfdf0` | Same suite — the composed HTTP registry was clearable and a post-composition mutation of a source policy changed `totalDeadlineMs` from 10000 to 999999. |
| LIVE-04 | Medium | `FIXED` | `f4bfdf0` | Same integration suite — a non-cooperative fetch and reader held the port result open; a body that finished after the deadline was admitted as SUCCESS. |
| LIVE-05 | High | `FIXED` | `f4bfdf0` | Same suite — a DEADLINE timeout emitted no `api.request.failed`. |
| LEG-01 | High | `FIXED` | `ca210d3` | `tests/integration/legacy-http-credential-authority.test.ts` — a recovery that answered after the deadline called `onUnauthenticated` once; it now calls it zero times, and only an adopted no-session result notifies. |
| LEG-02 | High | `FIXED` | `ca210d3` | Same suite — a bearer profile dispatched with no `Authorization` at all. |
| OPT-NET-01 | Medium | `FIXED` | `ca210d3` | `tests/unit/legacy-and-optional-network-remediation.test.ts` — a loader rejection with a live signal became `PAGINATION_ABORTED`. |
| OPT-NET-02 | Low | `FIXED` | `ca210d3` | Same suite — `defineMutationIntent` accepted control characters the executor rejected. |
| STO-RR-01 | High | `FIXED` | `6a8281a` | `tests/unit/opfs-worker-runtime.test.ts` — a strict non-reentrant lease manager made `FINALIZE_PUT` hang forever; `tests/unit/opfs-byte-store.test.ts` pins that a failed finalization is no longer a plain success. |
| STO-RR-02 | Medium | `FIXED` | `6a8281a` | Same suite — every failure answered with kind `CAPABILITIES`. |
| STO-RR-03 | Medium | `FIXED` | `6a8281a` | Same suite — `{code:"EVIL"}` reached the caller; a non-boolean `retryable` and a throwing getter left the RPC to time out. |
| STO-RR-04 | Medium | `FIXED` | `6a8281a` | `tests/unit/public-response-cache.test.ts` — a transient marker read failure deleted the active candidate. |
| STO-RR-05 | Medium | `FIXED` | `6a8281a` | Same suite — one failed repair fetch destroyed every healthy asset in the release. |
| RPC-RR-02 | Medium | `FIXED` | `bd90e0c` | `tests/unit/browser-rpc/browser-rpc-remediation.test.ts` — a throwing fence and a throwing `clock.sleep` escaped the Result contract. |
| RPC-RR-03 | High | `FIXED` | `bd90e0c` | Same suite — a transport accessor ran during validation, and the installed binding registries exposed `set`/`delete`/`clear`. |
| RPC-RR-04 | Medium | `FIXED` | `bd90e0c` | Same suite — extra, inherited, symbol-keyed and throwing-getter transport values passed. |
| SW-RR-01 | High | `FIXED` | `efc577d` | Bounded marker reader with a read deadline, reader cancel and fatal UTF-8 decode replaces `response.text()`. |
| SW-RR-02 | Medium | `FIXED` | `efc577d` | A `null` `event.source` no longer satisfies activation or reset completion. |
| SW-RR-03 | Medium | `FIXED` | `efc577d` | `tests/unit/service-worker-web-push-remediation.test.ts` plus the `check:adapter-inventory` gate — generator and decoder now share one exported table. |
| SW-RR-04 | Medium | `FIXED` | `efc577d` | `cache.match` rejection is closed as a miss so `respondWith` reaches its network fallback. |
| WP-RR-01 | Medium | `FIXED` | `efc577d` | `focus`/`openWindow` carry NOT_APPLIED → MAYBE_APPLIED → CONFIRMED and a late effect is observed exactly once. |
| TR-RR-08 | Medium | `FIXED` | `69cb7e3` | `tests/unit/resumable-upload-http-control-plane.test.ts` — a throwing getter escaped as `TypeError` out of `createSession`; symbol and non-enumerable extras passed the key check. |
| TR-RR-09 | Medium | `FIXED` | `fb5b449` | `tests/unit/image-cdn-runtime.test.ts` — the suite pinned the contradictory `private, no-store` as success; the recorded fail-closed matrix now applies. |
| GOV-01 | Low | `FIXED` | this commit | `scripts/check-adapter-inventory.ts` diffs `docs/reviews/adapters/INVENTORY.md` against `git ls-files src/adapters`. The missing `src/adapters/platform/abortable-operation.ts` row is restored and the total is 119/119. |
| GOV-02 | Medium | `FIXED` | this commit | This section replaces the over-closed rows with evidence-linked dispositions and an explicit not-done list. |
### Landed in the second pass
The twelve findings the first pass did not reach are now closed on the same
terms: a named adversarial test failed on the pre-fix source and passes on the
landed one.
| ID | Severity | Commit | Red-then-green evidence |
| --- | --- | --- | --- |
| RPC-RR-01 | High | `a7390e3` | `tests/unit/browser-rpc/browser-rpc-remediation.test.ts``openServerStream` returns a lease (`streamId`, `frames`, `cancel`, `waitClosed`) decoded from own data descriptors. A timed-out stream is cancelled exactly once, a second stream for the same operation is refused as `CONFLICT` / `RPC_STREAM_DRAINING` without reaching the transport, and admission resumes only after `waitClosed()` settles. |
| RT-RR-01 | High | `c0f53d1` | `tests/unit/realtime/stream-coordinator.test.ts` — a `close()` during a running apply reported success before the fix; tasks are now registered at invocation, so it reports `IDLE_TIMEOUT` and `DRAINING`. |
| RT-RR-02 | High | `c0f53d1` | Same suite — a queued event started running inside DRAINING, and a timed-out effect left its resume token in place. The queued event is now dropped as `CLOSED` at execution time and the token is discarded with `freshness: UNKNOWN`. |
| RT-RR-03 | Medium | `c0f53d1` | `tests/unit/realtime/live-poll-handoff-coordinator.test.ts` — a second `close()` replayed the cached timeout forever; only an in-flight close is shared now, fenced writers are retained until their tails settle, and a later close converges to success. |
| RT-RR-04 | High | `c0f53d1` | Same suite — `close()` reported quiescence while a checkpoint was still running; checkpoint work now joins the physical-task registry. |
| TR-RR-05 | High | `46e067e` | `tests/unit/abortable-operation.test.ts` — a rejection was reported as `TERMINAL/CLOSED` while `terminal()` said no owner, and a throwing scheduler released the caller listener leaving no owner at all, so later aborts were invisible. The primitive now distinguishes `REJECTED`, agrees with `terminal()`, snapshots the scheduler, closes atomically on install failure and compensates a late value exactly once. Both presigned subsystems migrated onto it, replacing two hand-written copies. |
| TR-RR-01 | High | `46e067e` | `tests/unit/presigned-transfer.test.ts``close()` released bookkeeping without aborting, and the consumer signal joined only after the fetch began. Both are fixed; the scheduler-failure test now pins fail-closed. |
| TR-RR-02 | High | `46e067e` | The upload scope is created before the digest and the digest races the caller and deadline; the vault claim and network call follow an owner re-check. |
| TR-RR-03 | High | `46e067e` | Same suite — the registration is a versioned exact union: unknown/missing protocol version, plaintext target, ambient credential and cookie headers, a non-2xx expected status and any extra own field are each refused at the issuer seam. |
| TR-RR-04 | Medium | `5a76f95` | Same suite — the presigned source was never closed on success, writer failure or abort; a holder now closes it exactly once at the outermost boundary on all three. |
| TR-RR-06 | High | `5a76f95` | `tests/unit/resumable-upload-runtime.test.ts` — a never-granting mutation lock made `dispose()` unbounded; it is now bounded by `cleanupDeadlineMs`, returns the drain result, and leaves the runtime `CLOSING` with the checkpoint store open when the drain is unproved. |
| TR-RR-07 | High | `5a76f95` | `tests/unit/image-cdn-runtime.test.ts` — after an abort a new verification was admitted while the abandoned verifier still ran; the slot is now held until the raw verifier settles. |
**No second re-review row remains `NOT_STARTED`**, and the
structural gate for the shared `abortable-operation` primitive is now active —
it was withheld until the primitive actually had production importers, because a
gate that fails CI for a documented but unfixed defect reports the wrong thing.
Contracts that changed shape, and are therefore breaking for an external
implementor:
| Contract | Change | Reason |
| --- | --- | --- |
| `BrowserRpcTransport.openServerStream` | returns `BrowserRpcServerStreamLease` instead of `AsyncIterable` | RPC-RR-01 needs cancellation and closure evidence |
| `AuthSessionPort.recover` | accepts an optional `CredentialOperationContext` | LEG-01; optional for one release |
| `PresignedCapabilityRegistration` | gains `protocol` | TR-RR-03 versioned exact union |
| `ResumableUploadRuntime.dispose` | returns `BrowserDataResult<void>` | TR-RR-06 bounded drain result |
| `ResumableUploadRuntimePolicy` | gains `cleanupDeadlineMs` | TR-RR-06 teardown bound |
| `ImageCdnPresentationPort.resolve` | `signal` required | BT-IMG-01, landed earlier |
### Gates after this pass
Run on the landed tree. Only what actually passed is claimed as passing.
| Command | Exit | Result |
| --- | ---: | --- |
| `corepack pnpm check:types` | 0 | all six projects |
| `corepack pnpm lint` | 0 | `--max-warnings=0` clean |
| `corepack pnpm check:architecture` | 0 | 289 modules, 868 dependencies; 12 fixtures PASS |
| `corepack pnpm check:adapter-inventory` | 0 | 119 files, 7 shared asset extensions, fixture linking, primitive importers |
| `corepack pnpm check:registries` | 0 | 11 registries PASS |
| `corepack pnpm check:diagnostics` | 0 | 8 diagnostics / 5 telemetry producers |
| `corepack pnpm check:browser-file-storage-boundaries` | 0 | PASS, 34 rejections |
| `corepack pnpm check:realtime-boundaries` | 0 | PASS |
| `corepack pnpm verify:documentation` | 0 | PASS_SCOPED |
| `git diff --check` | 0 | clean |
| `tests/unit` + `tests/integration`, no exclusions | — | 1643 passed / 1747; the 104 failures are the four environmental files below |
| `corepack pnpm test:component` | 0 | 126 passed |
| `corepack pnpm test:recipes` | 0 | 17 passed |
| `corepack pnpm test:reference-feature` | 0 | 26 passed |
### Environmental failures, not claimed as green
| Gate | Status | Attribution |
| --- | --- | --- |
| `tests/unit/ci-workflow-generation.test.ts` | 82 failed / 325 passed | Identical on the pre-change baseline (`git stash` comparison). The subprocess gates it spawns cannot run in this sandbox. |
| `tests/unit/ci-artifact-contract.test.ts` | fails | Unchanged pre-existing sandbox, cgroup and `/tmp` permission behaviour. |
| `tests/unit/security-followup.test.ts`, `tests/unit/provider-guardian-transaction.test.ts`, `tests/unit/risk-coverage.test.ts` | flaky under full-suite load | All three pass in a fresh process (78 passed together). They spawn and reap process groups, so their timing assertions are load sensitive. |
### Destructive fixture hazard — fixed
Outside the 38 findings, and found while running the suites for them.
Four sites linked the repository's installed dependencies into a throwaway
fixture with a single directory symlink at `<fixture>/node_modules`:
- `scripts/lib/removal-fixture.ts`
- `scripts/check-supply-chain-provider-fixtures.ts`
- `tests/integration/security-followup-archive.test.ts`
- `tests/unit/ci-artifact-contract.test.ts`
Each fixture then runs `pnpm` inside itself. pnpm does not recognise the modules
directory it finds there and purges it; with `CI=true` it does so without a
prompt. The purge followed the symlink and deleted the **repository's own**
`node_modules` mid-run — a test suite uninstalling the workspace it was running
in. That is what produced the cascading, file-unrelated failures a full
`test:unit` run reported, and it happened twice during this work.
`scripts/lib/fixture-node-modules.ts` replaces all four: `node_modules` is a
real directory whose entries are individual symlinks, so a recursive delete
unlinks the fixture's own links instead of walking through one link into the
shared tree. `tests/unit/fixture-node-modules.test.ts` performs the exact
recursive delete pnpm performs and asserts the source tree survives, and
`corepack pnpm check:adapter-inventory` fails on any reintroduction of the
directory-symlink form.
After the fix a full `tests/unit` + `tests/integration` run leaves the
dependencies intact and its failures are confined to the two environmental
files above plus the two flaky-under-load ones:
| File | Failed | Attribution |
| --- | ---: | --- |
| `tests/unit/ci-workflow-generation.test.ts` | 82 | Identical on the pre-change baseline (`git stash` comparison). Its subprocess gates cannot run in this sandbox. |
| `tests/unit/ci-artifact-contract.test.ts` | 19 | Unchanged pre-existing sandbox, cgroup and `/tmp` permission behaviour. |
| `tests/unit/security-followup.test.ts` | 2 | Passes in isolation. |
| `tests/unit/provider-guardian-transaction.test.ts` | 1 | Passes in isolation. |
1619 passed / 1723 total, and `tests/unit/removal-fixture.test.ts`,
`tests/unit/supply-chain.test.ts` and
`tests/integration/security-followup-archive.test.ts` — the three that had to be
excluded before — now pass in the full run.
## Third re-review (2026-08-14)
A third read-only re-review re-tested all 38 rows above against hostile,
non-cooperative, late-completing and mutable inputs. It confirmed 18 as fixed
and found 20 that held only on the paths their tests exercised, plus three new
findings and three governance defects. The common shape was the same in almost
every case: a value was **checked and then read again**, or a wrapper settled
and was mistaken for the physical work it was bounding.
`docs/operations/adapter-remediation-dispositions.json` is the machine-readable
record; `corepack pnpm check:remediation-ledger` joins it against this document,
verifies every named evidence path exists, and refuses a blanket closure
sentence while any row is still open. **GOV-03.** The previous section claimed
"All 38 are now FIXED" while six rows were reproducibly partial — a sentence is
cheap and a reviewer reads it as evidence, so the claim is now derived rather
than authored.
### Landed
| ID | Prior verdict | Disposition | Red-then-green evidence |
| --- | --- | --- | --- |
| NS-01 | `PARTIAL` | `FIXED` | `tests/integration/http-execution-v3-live-authority.test.ts` — a throwing `kind` getter escaped the auth boundary and an auth outage was reported as `NETWORK_FAILURE`; nine hostile credential shapes now close as `AUTH_INTEGRATION_FAILURE` with zero fetches, and each field is read exactly once. |
| NS-02 | `PARTIAL` | `FIXED` | `tests/unit/contract-registry-immutability.test.ts` — a policy that answered `10_000` to validation and `999_999` to the copy installed the second value; composition now snapshots first, so the out-of-ceiling value is refused. |
| NS-03 | `PARTIAL` | `FIXED` | `tests/integration/http-execution-v3-live-authority.test.ts` — a `NONE` probe left `body.locked === true` after a deadline; the reader is now cancelled once and its lock released. |
| NS-04 | `PARTIAL` | `FIXED` | `tests/unit/opfs-byte-store.test.ts` — a failed `journal.complete` still returned plain success with `SUCCEEDED` telemetry; it now returns a `RECONCILE` failure and leaves the row `COMMITTED`, and an unfinished delete is observed `DEGRADED`. |
| NS-05 | `PARTIAL` | `FIXED` | `tests/unit/opfs-worker-runtime.test.ts` — a bootstrap failure answered every request with kind `CAPABILITIES`, so the gateway replaced `BLOCKED` with `UNSUPPORTED`; all twelve kinds now round-trip their own correlation. |
| NS-06 | `PARTIAL` | `FIXED` | Same suite — a throwing `requestId` getter produced an RPC timeout and a stateful trap left the public promise pending forever; replies are decoded before the pending row is released and an uncorrelatable reply fails the channel closed. |
| NS-07 | `NEW` | `FIXED` | `tests/unit/cursor-pagination-runtime.test.ts` — raising `maxPages` after construction widened a validated cap from one page to three; caps and collaborators are captured once. |
| NS-08 | `NEW` | `FIXED` | `tests/unit/public-response-cache.test.ts` — a non-cooperative fetch held the mutation lock forever, and a digest finishing after the abort still wrote the asset and the activation marker; one terminal owner now covers the whole staging body. |
| RPC-01 | `PARTIAL` | `FIXED` | `tests/unit/browser-rpc/browser-rpc-remediation.test.ts` — a rejecting, throwing or non-promise `waitClosed()` was absorbed into success and a second physical stream opened; only a fulfilled contract-shaped receipt prunes the registration. |
| RPC-02 | `PARTIAL` | `FIXED` | Same suite — a throwing iterator `return` accessor replaced the selected timeout with a native `TypeError`, and the exported lease decoder threw on a hostile `Symbol.asyncIterator`. |
| RPC-03 | `PARTIAL` | `FIXED` | Same suite — a registry accessor ran twice during validation and rows hiding fields behind a prototype or a non-enumerable key installed; every registry is snapshotted before validation. |
| RPC-04 | `PARTIAL` | `FIXED` | Same suite — own `{ok,message,encodedBytes}` plus a prototype `injected` was a success, and a missing `message` reached a permissive schema as `undefined`. |
| RT-01 | `PARTIAL` | `FIXED` | `tests/unit/realtime/stream-coordinator.test.ts` — an authority that re-entered `close()` from inside its own invocation got `{ok:true}` while its effect was pending; the task is registered before the collaborator is called. |
| RT-02 | `NEW` | `FIXED` | Same suite — a throwing `scheduleTimeout` started a recovery that overlapped the running apply and made `close()` reject with a native `TypeError`; an uninstallable deadline now fails closed inside the result contract. |
| TR-01 | `PARTIAL` | `FIXED` | `tests/unit/presigned-transfer.test.ts` — a stateful issuer could show an allowed header set to the forbidden-header check and store `Authorization`; the registration and everything nested in it is snapshotted before validation. |
| TR-02 | `PARTIAL` | `FIXED` | Same suite — a source lease that resolved after an abort was never closed; a compensator sharing the holder's close-once latch closes it exactly once. |
| TR-03 | `PARTIAL` | `FIXED` | `tests/unit/abortable-operation.test.ts`, `tests/unit/image-cdn-runtime.test.ts`, `tests/unit/resumable-upload-fetch-transport.test.ts` — the outcome depended on a hard-coded four-microtask drain, and a throwing scheduler rejected `probe()`/`execute()` natively while leaking a caller listener. The primitive now settles once by observation order, and all four consumers use it with construction-time bound timer snapshots. |
| TR-04 | `PARTIAL` | `FIXED` | `tests/unit/resumable-upload-runtime.test.ts` — a provider outliving its attempt deadline let `dispose()` report a drained runtime and close the checkpoint store; raw provider work is now its own registry and both must be quiescent. |
| TR-05 | `PARTIAL` | `FIXED` | `tests/unit/resumable-upload-http-control-plane.test.ts` — a stateful `sessionId` passed the regex and returned `../../unsafe`; the decoder validates an owned snapshot read exactly once. |
| SW-01 | `PARTIAL` | `FIXED` | `tests/unit/service-worker-runtime.test.ts` — a single 1 MiB chunk was retained before the 257-byte ceiling was compared, a declared oversize left the body open and the reader lock was never released. |
| SW-02 | `PARTIAL` | `FIXED` | `tests/unit/service-worker-web-push-remediation.test.ts` — the generator emitted `/assets/bad@name-abcdefgh.js` and the decoder then refused the manifest it had just produced; both share one canonical path predicate and the generator self-validates its output. |
| WP-01 | `PARTIAL` | `FIXED` | `tests/unit/web-push-worker-runtime.test.ts` — an ordinary click was counted twice, a late rejection downgraded `MAYBE_APPLIED` to `NOT_APPLIED`, and the late observation ran outside `waitUntil`. |
| GOV-03 | `OPEN` | `FIXED` | `scripts/check-remediation-ledger.ts` — dispositions and evidence paths are machine-readable and a blanket closure sentence is blocked while any row is open. |
| GOV-04 | `OPEN` | `FIXED` | `scripts/check-adapter-inventory.ts` — the gate passed on any single importer; it now requires the four named consumers to resolve their import to the shared primitive and prints the exact set. |
| GOV-05 | `OPEN` | `FIXED` | `config/recipes/frontend-capability-recipes.json` — see the budget note below. |
### The file-transfer bundle budget
`check:optional-recipes:source` failed at the previous baseline too (52,078 >
52,000 gzip bytes), so it was not green before this work either. Duplicate abort
and deadline mechanics were consolidated first: the Image probe and the Resumable
fetch transport now use the shared `abortable-operation` primitive instead of
their own scopes, and four decoders share `src/contracts/exact-snapshot.ts`
rather than each carrying its own descriptor walk. The remainder is the
correctness code the third re-review asked for — exact decoders, late-value
compensators and physical-work registries — so the budget is reset to **54,600**
gzip bytes against a measured **53,810**, rather than the failure being carried
forward as if it were green.
### Regenerated evidence (this commit)
| Command | Exit | Result |
| --- | ---: | --- |
| `corepack pnpm check:types` | 0 | all six projects pass |
| `corepack pnpm check:architecture` | 0 | 290 modules, 879 dependencies; 12 fixtures PASS; allowed PASS / 9 forbidden rejected |
| `corepack pnpm check:adapter-inventory` | 0 | 119 files; 7 shared extensions; 5 shared-abort importers listed |
| `corepack pnpm check:optional-recipes:source` | 0 | file-transfer 53,810 / 54,600 gzip bytes |
| `corepack pnpm exec vitest run tests/unit/browser-rpc tests/unit/realtime` | 0 | 17 files / 234 passed |
| abortable-operation, presigned, resumable, image CDN | 0 | 7 files / 176 passed |
| OPFS, journal, public cache, cursor | 0 | 5 files / 100 passed |
| Service Worker + Web Push | 0 | 6 files / 79 passed |
| `corepack pnpm exec vitest run tests/integration` | 0 | 11 files / 82 passed |
The full `tests/unit` + `tests/integration` run is **1,845 passed / 1,864**,
128 of 129 files green. Every one of the 19 failures is in
`tests/unit/ci-artifact-contract.test.ts` and is the pre-existing sandbox,
cgroup, RLIMIT and `/tmp` permission behaviour already recorded above — the same
file failed identically before this work. No adapter test fails.
## Operational contract review (2026-08-15)
A fourth review looked past the adapter layer at the operational contract:
feature on/off, environment separation, folder boundaries, and which gates were
actually green. It found five red gates and three structural gaps. Every row
below names the defect, not the symptom.
| id | area | disposition | what was actually wrong |
| --- | --- | --- | --- |
| `OPS-01` | release | `FIXED` | `public/` is copied verbatim into `dist/`, so every build — production included — shipped the local runtime document. Runtime config now comes from `config/runtime/<profile>.json`. |
| `OPS-02` | release | `FIXED` | Release coherence proved the artifacts agreed with each other, never that they belonged in production. `FE-GATE-027` refuses an artifact whose `APP_ENV`, auth mode, endpoints or build identity do not match a declared `RELEASE_TARGET`, and refuses an undeclared target outright. |
| `OPS-03` | runtime | `FIXED` | `REQUEST_TIMEOUT_MS` was validated and then never passed to the V3 executor; every operation ran on its contract's own deadline. It is now a ceiling that may tighten a contract, never loosen one. |
| `OPS-04` | build | `FIXED` | `VITE_ROUTER_BASE_PATH` drove the router and the Service Worker scope but not Vite's asset `base`, so a sub-path deployment emitted root-absolute assets. One value now feeds all three. |
| `OPS-05` | provider | `FIXED` | bubblewrap 0.9.0 drops whatever follows the option stream inside an `--args` file, so the sandboxed command was never executed: bwrap printed usage and exited 1. Options stay hidden; the command travels on real argv. |
| `OPS-06` | provider | `FIXED` | The scope wrapper read its liveness pipe through `fs`, a blocking `read(2)` on a pipe the supervisor never closes. `process.exit` deadlocked joining that thread, so a completed provider was reported as a timeout kill. |
| `OPS-07` | release | `FIXED` | `mkdir`/`open` modes were left to the ambient umask, so a hardened runner produced directories it could not enter and handed `tar` a file it could not re-open. |
| `OPS-08` | release | `FIXED` | Promotion cleanup deleted this promotion's exact five through a pinned descriptor and only then noticed the leaf had been substituted, leaving a half-emptied directory a retry could not distinguish from a completed one. |
| `OPS-09` | removability | `FIXED` | The removal fixture was not a repository, had no `.gitignore`, and each removal script kept its own copy-target list that had drifted. Supply-chain generation therefore failed inside every fixture and took the whole provider suite down with it. |
| `OPS-10` | removability | `FIXED` | A platform integration file asserted the reference feature's route ids, so removing the feature left it importing a deleted module. The assertion moved to the feature's own test tree. |
| `OPS-11` | removability | `FIXED` | A removal fixture runs against a deliberately reduced CI contract; the canonical exact-count tests re-imposed the full authority on it and failed the fixture for the reduction it exists to prove. |
| `OPS-12` | browser | `FIXED` | Four browser-capability specs answered capability requests without the `protocol` field the hardened envelope requires, so every capability was refused and the download and part-upload paths asserted against an empty transcript. |
| `OPS-13` | browser | `FIXED` | A refused capability document answered `recovery: NONE`, contradicting both the design record and the vault, which already answers `REISSUE_CAPABILITY`. |
| `OPS-14` | performance | `FIXED` | Playwright matches accessible names by substring, so the navigation entry matched the home page's call to action too; the run died on a strict-mode violation before the first measurement and produced no evidence at all. |
| `OPS-15` | visual | `FIXED` | The platform overview baseline predated the reference routes moving from `integration-defined` to `session-required`, so the only visual gate covering that page failed for its own staleness. |
| `OPS-16` | architecture | `FIXED` | `src/contracts` imported `src/application` for the shared `Result` and the compatibility predicate; neither package owned the shared vocabulary. Both moved down to contracts. |
| `OPS-17` | architecture | `FIXED` | The documented "no adapter depends on another concrete adapter" rule had no executable form, and `diagnostics` imported a guard out of `telemetry`. The guard moved to the adapter kernel and the rule is now enforced with a same-directory backreference. |
| `OPS-18` | architecture | `PARTIAL` | Generic presentation still reads the installed-feature registries. The rule freezes the exact set of modules doing so today; a new edge fails. Lifting the assembly into `bootstrap` is not done. |
| `OPS-19` | documentation | `FIXED` | README and the manual accessibility checklist both claimed six routes while ten were registered, leaving four screens outside the declared manual review scope. The list is now derived from the route registry by `verify:documentation`. |
### Product feature selection (2026-08-15, second pass)
| id | disposition | what changed |
| --- | --- | --- |
| `OPS-20` | `FIXED` | Which features a build contains is now a declared manifest rather than five registries spreading a literal. `VITE_PRODUCT_FEATURES` narrows it at build time; a test fails if a new registry forgets to consult it. |
| `OPS-21` | `FIXED` | `FEATURE_OVERRIDES` in the runtime document takes an installed feature out of service without a rebuild. The router refuses its routes, not just the navigation, so a typed deep link cannot still mount it. |
| `OPS-22` | `FIXED` | Both inputs are subtractive by vocabulary: the override enum has no `ENABLED`, and a build-time selection naming a feature the source tree does not declare is refused rather than ignored. |
| `OPS-23` | `FIXED` | A sandbox that fails to launch now reports why. The supervisor consumed the child's output only to enforce a byte cap and discarded it, so a host restriction surfaced as an unexplained `exit=1`. Lines the sandbox tooling itself emits are kept; provider output is still discarded. |
An env var does **not** shrink the bundle, and the code says so. A static import
cannot be undone by a value, and making the import graph depend on a
configuration string is what §3.5 exists to prevent. Measured: `none` changes
the output by 58 bytes. Physical removal is FE-GATE-020's job.
### Host restriction discovered during this pass
`bwrap --unshare-net` no longer works on this machine:
```
$ printf '%s\0' --unshare-net --ro-bind /usr /usr ... | bwrap --args 3 -- /bin/true
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted
$ sysctl kernel.apparmor_restrict_unprivileged_userns
kernel.apparmor_restrict_unprivileged_userns = 1
```
That reproduction contains none of this repository's code. Earlier in the same
session the identical sandbox ran to completion, so the restriction became
active partway through. While it holds, 16 of the 108 provider tests cannot run
here — they need a sandbox the kernel will not grant. They are not counted as
green and not counted as product defects; under a host that permits the
namespace the same file was 107/108.
### Still red after this pass
*applies effective aggregate cgroup limits without exposing command or
credentials* was rewritten. It used to read the live process tree with one
`ps` per pid and assert mid-run, which lost a race against a sandbox that now
completes in a few hundred milliseconds; it records the tree from `/proc` every
5ms and asserts on the recording after the run. That restructuring is also what
revealed the host restriction above — the supervisor had been failing to launch
the sandbox and the test was dying on the observation first.
Tests that spawn processes, build archives and sign evidence were given a
30s budget instead of the 10s default sized for pure-JS unit tests. The default
was not raised: that would hide a genuinely hung test.
### FE-GATE-020 after this pass
| fixture | before | after |
| --- | ---: | ---: |
| reference feature | failed before its first assertion | 1,612 pass / 1 fail |
| optional recipe | 39 failures | 1,386 pass / 2 fail |
| browser file + storage | 40 failures | 1,006 pass / 3 fail |
| realtime | not reached | 1,159 pass / 1 fail |
Every remaining failure is one of the three environment-limited tests above.
Lab performance now produces evidence, and that evidence shows the
named-interaction budget missed on this machine (367724ms against 200ms). The
metric measures a full lazy-route navigation while the budget is an
INP-shaped 200ms, so the two do not describe the same thing. No budget was
changed to make this green.
WebKit remains unavailable in this environment (`libevent-2.1-7t64`,
`libavif16` are not installed), so 14 browser-capability specs and the WebKit
E2E project are unverified here. Chromium and Firefox are 28/28 and visual is
5/5.
## Rules for updating this ledger
- A row moves out of `NOT_STARTED` only with a linked red test, its green run, and the commit id.
- `PROMOTION_BLOCKED` rows never become `DEFECT`; they close through an authorized product
selection change with the browser/provider evidence named in the plan.
- Environmental gate failures are copied verbatim and are never claimed as green.