Files
tech-log-frontend/docs/superpowers/plans/2026-08-01-http-worker-adapter-remediation.md
T

11 KiB
Raw Blame History

HTTP Worker and Adapter Remediation Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Remove duplicate HTTP authorities, harden Service Worker activation bounds and identity, and decompose large browser adapters only after shared golden behavior is locked.

Architecture: Installed contract contributions are the HTTP source of truth and expose provider-neutral typed outcomes. Worker protocol V2 exchanges a canonical full-identity digest. Browser adapter facades remain stable while shared persisted schemas and cohesive internal modules are extracted.

Tech Stack: TypeScript 7, Fetch API, Service Worker API, IndexedDB, OPFS, React 19, Vitest 4, Playwright.

Global Constraints

  • Contract and application layers never import concrete adapter outcome types.
  • Production exports accept only BoundQuery and BoundMutation after migration.
  • Runtime timeout is a global ceiling applied over descriptor deadlines.
  • Worker marker reads are bounded even without Content-Length and cancel oversized/non-terminating streams.
  • Public adapter facades and product-default optional capability selection remain unchanged.
  • Extraction follows characterization tests; file length alone does not justify a split.

Task 1: Installed HTTP contract as single source of truth

Files:

  • Modify: src/features/reference-feature/contracts/reference-feature-contract.ts

  • Modify: src/features/reference-feature/contracts/reference-schemas.ts

  • Modify: src/contracts/external-contract-runtime.ts

  • Modify: src/contracts/api-operations.ts

  • Modify: src/contracts/rest-profiles.ts

  • Modify: src/contracts/schema-registry.ts

  • Modify: src/features/installed-feature-contracts.ts

  • Modify: src/bootstrap/runtime-adapters.ts

  • Modify: tests/features/reference-feature/reference-contract.test.ts

  • Modify: tests/runtime-schema/http-schema.test.ts

  • Modify: tests/integration/http-execution-contract.test.ts

  • Modify: tests/unit/http-execution-v3.test.ts

  • Add parity tests showing method/path/validators/retry/effect/deadline/byte bounds come from one contribution; createdAt accepts omitted or RFC3339 datetime and rejects arbitrary strings.

  • Run focused tests and confirm RED on duplicated descriptors and permissive date schema.

  • Make the installed contribution authoritative; generate temporary legacy views from it and migrate all production callers before deleting the legacy registries/codecs.

  • Apply REQUEST_TIMEOUT_MS as min(runtimeCeiling, descriptorDeadline) without replacing shorter descriptor deadlines.

  • Keep the deadline authoritative through response admission and body reads: a deadline-owned abort after headers must still return TRANSPORT_FAILURE / TIMEOUT, perform one attempt, and never enter retry sleep instead of being masked as RESPONSE_STREAM_FAILURE.

  • Treat credential resolution as a credential-only patch boundary: reject attempts to inject or overwrite Idempotency-Key (including case variants) or transport/query authority, and cover hostile patches in the executor regression table.

  • Prove diagnostic privacy against the full runtime seam with non-empty identity references; assertions over an empty diagnostic projection do not count as evidence that intent/key/query identity is absent.

  • Re-run focused tests, prove rg has zero production callers of removed registries, and commit with git commit -m "refactor: consolidate installed HTTP contracts".

Task 2: Provider-neutral typed operation outcomes

Files:

  • Create: src/contracts/operation-outcome.ts

  • Create: src/application/ports/contract-operation-executor.ts

  • Modify: src/features/reference-feature/adapters/reference-http-gateway.ts

  • Modify: src/bootstrap/runtime-adapters.ts

  • Modify: src/adapters/http/http-execution-v3.ts

  • Modify: tests/features/reference-feature/reference-contract.test.ts

  • Modify: tests/unit/runtime-adapters.test.ts

  • Add compile/runtime tests that unknown operation IDs and mismatched input/output types fail, and that the feature gateway has no import from src/adapters/http.

  • Run focused tests/typecheck and confirm RED because the port is operationId: string, input: unknown, and concrete HttpExecutionOutcome leaks inward.

  • Derive InstalledOperationMap from installed contracts, expose generic execute<K extends keyof Map>(operationId: K, input: Map[K]["input"], context) and map HTTP outcomes to provider-neutral contract outcomes at the adapter boundary.

  • Re-run tests, typecheck, and architecture; commit with git commit -m "refactor: type installed contract operations".

Task 3: Bound-only server-state exports

Files:

  • Modify: src/presentation/adapters/query/application-query.ts

  • Modify: src/presentation/adapters/query/index.ts

  • Modify: src/features/reference-feature/presentation/use-reference-feature.ts

  • Create: tests/helpers/legacy-application-query-harness.tsx

  • Modify: tests/component/application-query.test.tsx

  • Add type tests that production hooks reject raw query keys and raw mutation executors while bound definitions still compile.

  • Run typecheck and confirm current overloads accept raw forms.

  • Move legacy raw harness behavior under tests/helpers; remove LegacyMutationOptions and the raw query union from production exports; migrate feature callers to bindQuery/bound mutations.

  • Run focused component tests and typecheck; commit with git commit -m "refactor: expose bound server-state hooks only".

Task 4: Bounded Service Worker marker reader

Files:

  • Create: src/adapters/service-worker/bounded-worker-response.ts

  • Modify: src/adapters/service-worker/service-worker-lifecycle.ts

  • Modify: tests/unit/service-worker-runtime.test.ts

  • Add tests for oversized declared length, headerless oversized chunks, invalid UTF-8, malformed JSON, and a non-terminating stream. Assert reader cancellation and bounded completion.

  • Run corepack pnpm exec vitest run tests/unit/service-worker-runtime.test.ts and confirm RED because lifecycle calls response.text().

  • Implement realm-safe stream reads up to maxBytes + 1, fatal TextDecoder, explicit cancellation, and strict marker parsing. Never call Response.text() for protocol data.

  • Re-run tests and commit with git commit -m "fix: bound Service Worker activation markers".

Task 5: Service Worker protocol V2 full identity

Files:

  • Modify: src/contracts/service-worker.ts

  • Modify: src/adapters/service-worker/service-worker-protocol.ts

  • Modify: src/adapters/service-worker/service-worker-entry.ts

  • Modify: src/adapters/service-worker/service-worker-lifecycle.ts

  • Modify: src/adapters/service-worker/service-worker-page-controller.ts

  • Modify: src/bootstrap/register-service-worker.ts

  • Modify: scripts/generate-build-manifest.ts

  • Modify: tests/unit/service-worker-runtime.test.ts

  • Modify: tests/unit/service-worker-build-input.test.ts

  • Add a tuple-mutation table for protocol/cache schema/build/release/contract/static set; each mutation must change the digest and reject activation. Add a valid ACTIVE fixture build that recomputes static set digest from asset entries.

  • Run focused tests and confirm RED because protocol V1 compares partial fields.

  • Set SERVICE_WORKER_PROTOCOL_VERSION = 2, define canonical sorted identity serialization, compute SHA-256 over every identity field, and exchange/validate the digest on every page-worker message.

  • Keep default capability selection null; use ACTIVE only in the explicit fixture build.

  • Re-run focused tests and the supported fixture build; commit with git commit -m "fix: bind Service Worker activation to full identity".

Task 6: Shared IndexedDB persisted-row schema

Files:

  • Create: src/adapters/storage/indexeddb/indexeddb-persisted-schema.ts

  • Modify: src/adapters/storage/indexeddb/indexeddb-types.ts

  • Modify: src/adapters/storage/indexeddb/indexeddb-runtime.ts

  • Modify: src/adapters/storage/indexeddb/indexeddb-maintenance.ts

  • Create: tests/fixtures/indexeddb/persisted-rows.ts

  • Modify: tests/unit/indexeddb-runtime.test.ts

  • Modify: tests/unit/indexeddb-maintenance.test.ts

  • Before extraction, run the same accepted/rejected record, receipt, retention, and budget golden rows through runtime and maintenance and assert identical verdicts.

  • Confirm RED on at least one drift fixture using the duplicate current guards.

  • Move persisted types/guards into the shared module; runtime and maintenance import it without behavior changes.

  • Re-run both large suites and commit with git commit -m "refactor: share IndexedDB persisted schemas".

Task 7: Cohesive browser adapter decomposition

Files:

  • Modify: src/adapters/storage/opfs/opfs-worker-runtime.ts

  • Create: src/adapters/storage/opfs/opfs-worker-bootstrap.ts

  • Create: src/adapters/storage/opfs/opfs-worker-message-host.ts

  • Create: src/adapters/storage/opfs/opfs-worker-core.ts

  • Create: src/adapters/storage/opfs/opfs-worker-lock.ts

  • Create: src/adapters/storage/opfs/opfs-physical-io.ts

  • Modify: src/adapters/cache-storage/public-response-cache-adapter.ts

  • Create: src/adapters/cache-storage/public-cache-manifest.ts

  • Create: src/adapters/cache-storage/cache-lock.ts

  • Modify: src/adapters/browser-files/download-delivery-adapter.ts

  • Create: src/adapters/browser-files/download-browser-managed.ts

  • Create: src/adapters/browser-files/download-picker-stream.ts

  • Create: src/adapters/browser-files/download-object-url.ts

  • Modify: tests/unit/opfs-worker-runtime.test.ts

  • Modify: tests/unit/public-response-cache.test.ts

  • Modify: tests/unit/browser-file-download.test.ts

  • Add golden facade tests for all success/failure/cancellation/lock-loss branches before moving code; snapshot externally observable operation order and error kinds.

  • Run the three focused suites and capture GREEN characterization evidence.

  • Extract OPFS bootstrap, host, core state machine, Web Lock, and physical I/O without changing public exports. Do not split the core state machine further.

  • Extract public-cache manifest codec/digest and generic lock logic behind the same facade.

  • Extract browser-managed, picker streaming, and object-URL download strategies behind the same delivery facade.

  • Re-run the same golden suites after each extraction. Any failure is a refactor regression, not a fixture update.

  • Commit each adapter independently with refactor: decompose OPFS worker adapter, refactor: extract public cache internals, and refactor: extract download delivery strategies.

Task 8: HTTP/worker/adapter verification

  • Run all focused tests named in Tasks 17.
  • Run corepack pnpm check:architecture, corepack pnpm check:types, and corepack pnpm lint.
  • Run corepack pnpm test:all.
  • Run supported Service Worker, IndexedDB, OPFS, public-cache, and download Playwright capability specs.
  • Run git diff --check and report unsupported browser gates without claiming success.