II.
Page overview
Reference · livepage:docs-specs-platform-gaps-20-functionality-coverage
Spec 20 — Functionality coverage (WP-FN-*) overview
Inspect the raw attributes, linked wiki pages, and inbound or outbound graph edges for page:docs-specs-platform-gaps-20-functionality-coverage.
Attributes
nodeKind
Page
sourcePath
docs/specs/platform-gaps/20-functionality-coverage.md
sourceKind
repo-docs
title
Spec 20 — Functionality coverage (WP-FN-*)
displayName
Spec 20 — Functionality coverage (WP-FN-*)
slug
docs/specs/platform-gaps/20-functionality-coverage
articlePath
wiki/docs/specs/platform-gaps/20-functionality-coverage.md
article
# Spec 20 — Functionality coverage (WP-FN-*)
Date: 2026-09-27 · Status: Gate-B draft · Binding decisions: **D8, D11, D12, D13, D14** and amendment **D17–D21** (`docs/specs/platform-gaps/00-intent.md:19-46`).
Inputs consumed in full: the Gate-A-approved adoption proposal `research/synthesis-adoption-proposal.md` (definitive 40-ID survivor register §3, planned 23-WP inventory §4.2, per-component decisions §1); dossiers R1 `research/fabric-current-state.md` (audit refresh §2, wiring map §3, gap-corpus index §5), R4 `research/delta-map.md` (must-survive planes, remote-access row D); sibling specs `10-t3code-migration.md` (WP-T3-01…33 — referenced, never restated) and `15-private-isolation-rename.md` (WP-RN-01…13; §3 name matrix). Citations: `fabric:` paths relative to `C:/work/fabric` at HEAD `5e46b998e`; `company/` = `C:/work/company`; all `path:line` cites carry the dossier section that verified them at HEAD.
**ID convention.** Work packages here are `WP-FN-01 … WP-FN-24`. The short form `F-<n>` used by the Gate-A proposal and by specs 10/30/40/50 refers to the same packages one-to-one (`F-01` ≡ `WP-FN-01`, …, `F-23` ≡ `WP-FN-23`). **Count: 24 vs the proposal's planned 23** — the single addition, WP-FN-24, is justified in §3.2: the intent's brief requires *every* orphaned/unwired capability found in research to become a wire-or-descope work package, and R1 §3.1 surfaces one orphan (`adapters/proxy`, the standalone Python proxy) that the proposal's inventory did not assign to any WP in any spec. No WPs were removed or merged.
---
## 1. Scope, invariants, non-goals
In scope: (a) the **D8 survivor register** — all 40 refreshed-audit IDs absorbed as work packages (§2); (b) **newly found orphaned/unwired capabilities** from the research dossiers, each with a wire-or-descope recommendation (§3); (c) the **guaranteed hosted-remote-access gap** (D12) as coverage-side requirements (§4); (d) **fabric-unique plane preservation** requirements where coverage work interacts with the t3code migration (§5).
Binding invariants (shared with spec 10 §1, restated where they bind coverage WPs):
1. **Public repo untouched (D17).** No WP below reads from, writes to, or republishes anything in public `a5c-ai/babysitter`. WP-FN-23's HYG4 item touches the **private company repo** (`C:/work/company`), which is neither the fabric repo nor the public babysitter repo — the D17 invariant is preserved (noted in that WP).
2. **Current names for existing code (spec 15 interaction rule 3).** WPs reference existing fabric code by its current paths (`packages/babysitter-sdk/…`, `packages/kradle/…`, `KIP_*` env vars); the RN-2…RN-5 sweeps rename these units together with the rest of the tree, and nothing here waits on them. New *packages* are not minted by this spec — new code lands inside existing workspaces; the one naming interaction is noted per-WP where it exists (e.g. WP-FN-09's memory backend is `@fabricstack/memory` after WP-RN-05).
3. **Registry (D19).** No WP here changes publishing; where a WP adds CI jobs they run in fabric's private pipelines only, and any package publication they touch targets the GCP Artifact Registry per spec 15 §4 (guards G1–G6 apply).
4. **Effect boundary B4 (Gate A §2.1).** Every fix in babysitter-sdk, trust-core, kip-sdk, atlas, kradle-core, and observer-dashboard is **plain TS** — the ledger/replay/session/parallel clusters (WP-FN-01…08) explicitly do not adopt Effect. This is the platform's most safety-critical code; entangling correctness fixes with a paradigm rewrite is forbidden by the approved proposal.
5. **Mobile deferred (D13).** No WP below specifies mobile surfaces; WP-FN-16's remote-access requirements are stated for server/web/desktop clients only.
6. **No implementation in this run (D4).** This document specifies; implementation is later babysitter runs executing the WPs.
Non-goals (owned by siblings; cross-referenced, never restated): t3code unit landings, lanes, and the ACP re-platforming (spec 10 — WP-FN-18 closes *lanes-green coverage*, WP-T3-07/08/09/12 build the lanes); rename/split mechanics (spec 15); CI gating of existing suites, e2e matrices, unit floors (spec 30 — TEST1→Q-01, TEST2→Q-08 per the register); exports maps, versioning, installers (spec 40 — HYG2→P-01/P-02 per the register).
---
## 2. Survivor-register absorption (D8) — the 40-ID map
The Gate-A register (`synthesis-adoption-proposal.md` §3, re-verified per-ID at HEAD in R1 §2 with fresh `path:line` evidence; **zero findings fully fixed**) is absorbed as follows. Every ID appears in **exactly one** work package's "Findings closed" list; per the register's binding "Absorbed by" column, three IDs are closed by sibling-spec WPs and are cross-referenced here for completeness, not duplicated:
| IDs | Absorbing WP | Cluster |
|---|---|---|
| C1, H1, S6 | WP-FN-01 | Provable ledger: journal integrity |
| C2 | WP-FN-02 | Provable ledger: journal signing |
| C3, H10, M8 | WP-FN-03 | Attestation default-covered flip + fail-closed gates |
| H2, H3, H4, S3 | WP-FN-04 | Replay-safety: key correctness |
| H5, H6, M5, S5 | WP-FN-05 | Execution control: cancellation/timeouts |
| H7, H8, M6, M7, S2, S4 | WP-FN-06 | Session/effect lifecycle residuals |
| M1, M2, M3, M4, S1 | WP-FN-07 | Parallel/async semantics |
| H9 | WP-FN-08 | Trust chains: human-root in the verifier |
| CAP1 | WP-FN-09 | Memory-system unification |
| CAP2 | WP-FN-10 | Budgets at dispatch |
| CAP3 | WP-FN-11 | Campaigns / scheduler preemption |
| CAP4 | WP-FN-12 | Improvement outer loop |
| CAP5 (residual) | WP-FN-13 | Inference scale-to-zero |
| CAP6 (residual) | WP-FN-14 | Session pause/resume/fork/rewind |
| KIP-TODO | WP-FN-15 | KIP security completion |
| HYG1 (residual) | WP-FN-22 | Secret redaction in the logging layer |
| HYG3, HYG4 | WP-FN-23 | Hygiene closure |
| TEST1 (residual) | **Q-01 (spec 30)** | CI gating of ungated suites — register-assigned to the testing spec |
| TEST2 | **Q-08 (spec 30)** | Adversarial ledger suite — recommended, outside the D7 bar; builds on WP-FN-01/02/04 behavior |
| HYG2 (residual) | **P-01/P-02 (spec 40)** | Wildcard-dep elimination + versioning discipline |
Coverage check: 37 IDs closed by WP-FN-* below (the 17 cluster rows above) + 3 by the register's named sibling WPs = **40 — the full register**, each ID appearing exactly once. For every CHANGED ID (H7, H8, H9, H10, M6, CAP5, CAP6, HYG1 — the in-scope eight), the WP objective is the **residual stated verbatim in R1 §2**, not the original 2026-09-14 wording.
---
## 3. Newly found orphaned/unwired capabilities (wire-or-descope register)
### 3.1 Dispositions decided by this spec
Every orphan below was found by the research dossiers (not the 2026-09-14 register) and becomes, or joins, a work package with an explicit recommendation:
| # | Orphaned/unwired capability | Evidence | Recommendation | WP |
|---|---|---|---|---|
| O1 | `apps/commander` — full operator board (51 test files, Playwright) running **entirely on a mocked, seeded backend**; zero workflow references; "the largest fully-orphaned functional surface in the repo" | R1 §3.9 (`apps/commander/README.md` intro; `SPEC-LIVE-BACKEND.md` unbuilt) | **WIRE** — via `SPEC-LIVE-BACKEND.md`, retargeted at the contracts RPC surface | WP-FN-17 |
| O2 | kip-sdk — 114 test files, 7,005-line repo engine, **zero consumers** in genty/kradle/adapters | R1 §3.5, CAP1 (`packages/kip-sdk/src/kip-repo.ts`) | **WIRE** as the platform memory backend (ADR-gated) | WP-FN-09 |
| O3 | genty `long-term-memory.json` extraction — written by the session module, **consumed nowhere else**; duplicated file in runtime | R1 §2 CAP1 (`packages/genty/platform/src/session/memoryExtraction.ts:45-47`, mirrored in `genty/runtime/src/session/memoryExtraction.ts`) | **WIRE-through** — becomes a write-through client of the unified memory backend; the duplicate module is deleted | WP-FN-09 |
| O4 | genty session `rewind.ts`/`tree.ts` — only consumer is a CLI export command; agent loop has a `'paused'` status string but zero pause handling | R1 §2 CAP6 (`genty/runtime/src/session/{rewind,tree}.ts`; `genty/core/src/loop/types.ts:97`; no `pause` hits in `agent-loop.ts`) | **WIRE** into the loop and the control surface | WP-FN-14 |
| O5 | kip-sdk `learn/` (compile.ts 242 + index.ts 749 lines) — no incumbent-comparison/promotion logic, no orchestrating consumer | R1 §2 CAP4 | **WIRE** as the evaluation stage of the improvement outer loop | WP-FN-12 |
| O6 | `adapters/proxy` — standalone **Python** package (own pyproject/Docker) outside the TS test lattice, duplicating the model-proxy role of `adapters/transport` | R1 §3.1 | **DESCOPE (retire)** unless implementation surfaces a distinct production consumer — the TS transport adapter is the model gateway of record (spec 15 §3.1 row 19) | WP-FN-24 |
| O7 | Realtime media plane — control plane real, media implementations DONE-but-live-pending (fake-device publish in production path) | R1 §3.2/§5 (`docs/research/realtime-agent-gaps.md` G0-RT, G1–G4) | **WIRE** to live-proven, with a staged descope option for GPU-quality avatar rendering only | WP-FN-21 |
Orphans found by research but **owned elsewhere** (cross-referenced so the register is complete, per the no-overlap rule): the 7 genty device shells + desktop scaffold (retired by WP-T3-27, D2c); genty-ui's duplicated `protocol/v1.ts` (deleted by WP-T3-27); the gateway short-code pairing store (upgraded by WP-T3-30); `adapters/harness-mock/src/multi-execution.ts` at 0 lines and the four zero-test packages (Q-02, spec 30); observer-dashboard's un-invoked Playwright config (Q-05, spec 30).
### 3.2 Count adjustment justification
The proposal's §4.2 inventory (23 WPs) predates the O6 finding's assignment: R1 §3.1 records `adapters/proxy` but no F/T/Q/P WP claims it, and the brief for this spec mandates a wire-or-descope WP for every orphan. WP-FN-24 (size S) closes that hole. All other orphans map onto the planned 23 without change.
### 3.3 Pre-existing gap corpora — absorption by reference (R1 §5)
These documents are absorbed **by reference**; their items are closed under the owners below, never re-derived here:
| Corpus | Owner |
|---|---|
| `docs/agent-layer-gaps.md` (47 agent-core gaps + runtime/platform/adapter gaps) | WP-FN-19 (item-level disposition table is its acceptance artifact) |
| `docs/hard-coded-and-should-be-in-graph-gaps-backlog.md` (~201 literals) | WP-FN-20 |
| `docs/research/realtime-agent-gaps.md` | WP-FN-21 |
| `docs/harness-features-backlog/gaps/` (149 files, 22 categories) | Category routing: harness-adaptation → WP-T3-06…13; breakpoint-workflows → WP-FN-03 + WP-T3-23; parallelization, effect-routing, process-composition, run-lifecycle, state-continuity → WP-FN-04/05/07 cluster; session-management → WP-FN-06/14; agent-delegation, json-interaction, prompt-engineering, tools-capabilities → WP-FN-19; mcp-channels → WP-T3-33; security → WP-FN-03/08/22; observability, observer-integration, subagent-observability → WP-FN-22 + Q-05; remote-integration → WP-FN-16; ecosystem → spec 40 (P-07/P-08); performance, profile-orchestration, user-experience → R-01 triage (spec 50). WP-FN-19's disposition table records the item-level routing for every file in the corpus. |
| `docs/genty-features-backlog-updated/gap-status-matrix.md` (165 rows, all claimed CLOSED) | Claims, not facts (R1 §5); any row reopened during WP-FN-19's disposition pass joins its table |
| `docs/atlas-library-gaps.md` | CLOSED (456/456 connected) — cited as done, no WP |
| `MATURITY-MATRIX.md` | Baseline for spec 30 |
| `docs/adapters/terminology-and-structure-gaps/*`, `docs/blueprints-rename/` | Spec 15 (D20) |
| `docs/v6-spec-and-roadmap/` | Superseded by this spec set |
---
## 4. The guaranteed hosted-remote-access gap (D12) — coverage-side requirements
D12 makes hosted remote access a coverage-spec gap *regardless of research findings*; R1 §3.10 confirms it is also empirically real — **zero** ssh-tunnel/tailscale/relay code exists in fabric; the only seeds are gateway bearer tokens and the in-memory 8-digit/5-minute short-code pairing (`fabric:packages/adapters/gateway/src/pairing/short-code.ts:1-20` — R4 §D.1). kradle being cloud-deployed on GKE is hosted *control plane*, not remote access to a user's environment (R4 §D.1).
This spec owns **what the platform must functionally provide**; the *mechanics* are t3code-adopted and owned by spec 10 (WP-T3-28 ssh, WP-T3-29 tailscale, WP-T3-30 environment auth/pairing, WP-T3-31 relay, WP-T3-24 client connection catalog). The coverage requirements, binding on WP-FN-16:
- **FR-1 Four routes, one auth.** An authorized user reaches their environment's contracts-RPC surface from anywhere via: direct/LAN DPoP pairing, Tailscale as an ordinary pairing endpoint (not a separate environment type), SSH bootstrap + port-forward, and the hosted relay. Every route terminates at the same environment auth (R4 §D.6).
- **FR-2 Broker-not-proxy.** The hosted relay mints no credentials and never sees session tokens; after bootstrap it does not proxy traffic (`t3:docs/internals/t3-connect.md:3-33` trust model, adopted verbatim per Gate A §1.4).
- **FR-3 Org scoping.** Relay-registered environments are scoped to kradle orgs (`fabric:packages/kradle/core/src/org-scoping.js:5` — R4 §D.4.2); cross-org access attempts are denied and audited. Identity is kradle org identity, never a parallel consumer-IdP (Clerk substitution, Gate A §1.4).
- **FR-4 One PKI.** Relay envelope verification is anchored on trust-core key/chain machinery (`fabric:packages/trust-core/src/index.ts:1-7` — R4 §D.4.1); no second signing substrate ships.
- **FR-5 Pairing UX.** The short-code UX slot survives as DPoP-bound pairing grants (upgrade, not delete-and-reinvent — R4 §D.4.3), reachable from the console surfaces.
- **FR-6 Journal/provenance unbroken.** A remotely-driven session produces the same journal/run binding, approval gating, and attestation records as a local one (§5 planes).
- **FR-7 Operational story.** The relay's ops surface (Cloudflare Worker + Postgres + identity — R2 §16 via Gate A §1.4.4) has a documented runbook and its packaging/rollout is carried by specs 40/50.
Mobile clients are out of scope for all seven requirements (D13).
---
## 5. Fabric-unique plane preservation (coverage ↔ migration interaction)
R4's must-survive constraints bind every WP here that touches a plane the migration is re-platforming. Three rules, binding:
1. **Journal sovereignty.** Run identity, provenance, and replay stay with the babysitter journal (`fabric:packages/babysitter-sdk/src/storage/journal.ts:72-82`; kanban reads `.a5c/runs` — R4 spec input 8). WP-FN-01/02 *harden* that journal (checksums, chain, signatures); WP-T3-16 *enforces* that every migrated lane still terminates in it. Ordering consequence: the journal event format changes of WP-FN-01/02 land **before or together with** WP-T3-16's enforcement suite so the sovereignty tests assert the hardened format, not the legacy one.
2. **Approval taxonomy.** The 7-action `AgentApproval` set (`fabric:packages/kradle/core/src/agent-approval-controller.js:15` — R4 §B.4.2) and signed breakpoints chained to human roots (`fabric:packages/adapters/policy/src/proven-bridge.ts:92-119`) are a strict superset of t3code approvals. WP-FN-03's fail-closed flip and WP-FN-08's verifier-level human-root requirement apply to the *mapped* approval surface WP-T3-23 builds — the migration may not introduce an approval path that bypasses the flipped posture.
3. **Trust chains.** trust-core is the single signing substrate (R4 §B.4.5, §D.4.1). WP-FN-08's `requiredRootKind` lands in the chain verifier itself so every new consumer the migration creates (drive-lane permission callbacks WP-T3-17, environment auth WP-T3-30, relay envelopes WP-T3-31) inherits the human-root guarantee without re-implementing it one layer up.
---
## 6. Sequencing (D11)
D11 orders the roadmap: t3code migration first, functionality coverage second. Within that: the **plain-TS correctness clusters WP-FN-01…08 have no dependency on any WP-T3-*** (they live in babysitter-sdk/trust-core/genty-platform, all B4 no-Effect zones) and may run in parallel with migration from day one — the only coupling is the §5.1 ordering rule (WP-FN-01/02 before WP-T3-16's suite freeze). The capability WPs (WP-FN-09…21) mostly depend on migration landings and sequence after them. Spec 50's R-01 owns the merged cross-spec graph; sizes below feed it.
---
## 7. Work packages
### WP-FN-01: Journal integrity — checksum verification on load, hash chain, canonical JSON
- **Objective**: Make the journal tamper-evident: verify per-event checksums on load (today `parseJournalFile` only `JSON.parse`s and copies the stored `checksum` field without recomputing — `fabric:packages/babysitter-sdk/src/storage/journal.ts:111-141,151-161,132`, R1 §2 C1); hash-chain events so tail truncation is detectable (no `prevHash` exists; `EffectIndex.validateSequence` at `runtime/replay/effectIndex.ts:144-185` passes when tail files are deleted — R1 §2 H1); compute checksums over canonical JSON instead of `JSON.stringify(payload, null, 2)` (`journal.ts:77-78` — R1 §2 S6).
- **Findings closed**: C1, H1, S6.
- **Affected paths**: `packages/babysitter-sdk/src/storage/journal.ts` (write `:72-82`, load `:111-161`); `packages/babysitter-sdk/src/runtime/replay/effectIndex.ts` (`loadJournalSafe:374-380`, `validateSequence:144-185`); new `packages/babysitter-sdk/src/storage/canonical-json.ts`; journal format-version marker in the event envelope.
- **Acceptance criteria**: (1) every event loaded has its checksum recomputed over canonical bytes and compared; mismatch raises a typed `JournalIntegrityError` naming file+seq — never a silent skip; (2) every appended event carries `prevHash` of its predecessor's canonical bytes plus a persisted head pointer; deleting or truncating any tail region fails load with a typed truncation error (test proves the exact R1 H1 attack); (3) canonicalization is key-order- and whitespace-independent (golden vectors: same logical payload, different insertion orders → one checksum); (4) journals are format-versioned; pre-existing v1 journals load in an explicit `unverified-legacy` mode that journals a loud downgrade marker (D10: no shims — new runs write v2 only); (5) `loadJournalSafe` propagates integrity errors distinctly from parse errors.
- **Test requirements**: tamper suite — bit-flip, field reorder, tail truncation, mid-file event deletion, checksum-field forgery; canonicalization golden vectors; legacy-journal downgrade-marker test. This suite is the substrate Q-08 (spec 30) extends adversarially.
- **Dependencies**: none upstream; feeds WP-FN-02 (canonical bytes are the signing input) and the §5.1 ordering rule vs WP-T3-16.
- **Size**: M
### WP-FN-02: Journal event signing via trust-core
- **Objective**: Sign journal events. Today the appended payload is `{type, recordedAt, data}` + sha256 only — no SignedEnvelope, no principal — while trust-core signing is already consumed by adapters/policy/tools/transport and genty-core but the journal bypasses it (`fabric:packages/babysitter-sdk/src/storage/journal.ts:72-82` — R1 §2 C2).
- **Findings closed**: C2.
- **Affected paths**: `packages/babysitter-sdk/src/storage/journal.ts` (append/load); new signing seam module in `packages/babysitter-sdk/src/storage/` calling `packages/trust-core` payload-signing (`fabric:packages/trust-core/src/index.ts:1-7` export families — R4 §B.4.5); run-key configuration in `packages/babysitter-sdk/src/config/`; babysitter-sdk gains a plain-TS dependency on trust-core (B4-compliant — trust-core is plain TS).
- **Acceptance criteria**: (1) when a run signing key is configured, every appended event carries a trust-core signature envelope binding principal + canonical payload bytes + `prevHash` (chain-inclusive, so re-signing a tampered chain requires the key); (2) a verification API validates a journal's full signature chain and is invoked by the same load path as WP-FN-01's checks; (3) unsigned mode is legal but **loud**: the first event of an unsigned run is a journaled `journal-signing-disabled` marker (posture symmetry with WP-FN-03); (4) key provisioning is documented and wired into the packaged-install flow by cross-reference (spec 40 P-04 provisions a default run key so the shipped platform signs by default); (5) forged-signature and wrong-principal fixtures fail verification with typed errors.
- **Test requirements**: sign/verify round-trip; forged-envelope, swapped-principal, resigned-truncation negative tests; unsigned-marker presence test.
- **Dependencies**: WP-FN-01 (canonical bytes + chain), WP-FN-08 (chain-verification semantics it consumes).
- **Size**: M
### WP-FN-03: Attestation default-covered flip + fail-closed policy gates
- **Objective**: Flip the platform's attestation/policy posture from opt-in to default-covered. Residuals verbatim (R1 §2): C3 — enforcement activates only when `POLICY_CONFIG_ROOT_FP` is set, with a fast path constructing **no gate** when unset and "still no loud journaled 'attestation disabled' marker for the default run" (`fabric:packages/genty/platform/src/harness/internal/createRun/orchestration/policy-enforcement-wiring.ts:123-124,132-137`); H10 — producers wired but opt-in: proxy attestation behind `AGENT_MUX_PROXY_ATTESTATION_ENABLED` default `undefined` (`fabric:packages/adapters/transport/src/server.ts:1596-1607`, `transport/src/config.ts:47,21`), in-process model-decision signing only when `modelAttestationKey` configured (`fabric:packages/genty/core/src/session.ts:1452-1508,1460-1461`) — "the unconfigured platform still runs fully unattested"; M8 — uncovered dispatch actions return `{allowed: true}` and the error path also allows (`policy-dispatch-gate.ts:67-71,:96` region).
- **Findings closed**: C3, H10, M8.
- **Affected paths**: `packages/genty/platform/src/harness/internal/createRun/orchestration/policy-enforcement-wiring.ts`; `packages/genty/platform/src/harness/internal/createRun/orchestration/policy-dispatch-gate.ts`; `packages/adapters/transport/src/{server.ts,config.ts}`; `packages/genty/core/src/session.ts` attestation seam; install/config defaults (cross-ref spec 40 P-04 for key provisioning at install).
- **Acceptance criteria**: (1) a run starting without a pinned policy anchor journals a loud `attestation-disabled` event (queryable, surfaced by observer views) — no silent back-compat fast path; (2) with keys present (the packaged default), proxy attestation and in-process model-decision signing are ON without env opt-ins — the opt-*out* is the explicit configuration; (3) `verifyDispatchAuthorization` fails closed: uncovered actions are denied with a typed journaled denial; the only escape is an explicit, signed allowlist entry; the internal error path denies, never allows; (4) the flipped posture governs the migrated approval surface too: drive-lane permission callbacks (WP-T3-17) and the mapped 7-action taxonomy (WP-T3-23) cannot construct an ungated path (integration test at the seam); (5) live-stack lanes still pass with attestation on (no hidden dependency on the unattested fast path).
- **Test requirements**: posture matrix tests (anchor × proxy key × model key, 8 combinations — each asserts gate construction + journal markers); fail-closed unit tests incl. error-path denial; one live-stack lane run with default-covered posture asserted via the `provider-trace-redacted`/attestation artifacts.
- **Dependencies**: WP-FN-08 (verifier-level root-kind); coordinates with WP-T3-17/23 (§5.2); spec 40 P-04 (key provisioning).
- **Size**: M
### WP-FN-04: Replay-key correctness — value digests, stable keys, mismatch detection
- **Objective**: Make replay keying sound. Verbatim gaps (R1 §2): H2 — `hashArgsShape` reduces every primitive to `typeof value`, so a changed arg value silently replays the stale result (`fabric:packages/babysitter-sdk/src/runtime/intrinsics/task.ts:255-258,264-276`); H3 — `deriveStableTaskKey`'s per-shape occurrence counter shifts when a step is inserted, with no warning when `idx > 0` is relied on (`task.ts:245-253,249-252`); H4 — `EffectIndex.getByInvocation` returns `undefined` on miss and the caller silently requests a new effect; resolved-but-never-consulted keys are never diffed (`runtime/replay/effectIndex.ts:124-126`, `task.ts:94`); S3 — no runtime guard against un-keyed same-shape conditional skipping (INFERRED from unchanged H2/H3 code — R1 §2).
- **Findings closed**: H2, H3, H4, S3.
- **Affected paths**: `packages/babysitter-sdk/src/runtime/intrinsics/task.ts` (key derivation `:245-276`, replay consult `:94`); `packages/babysitter-sdk/src/runtime/replay/effectIndex.ts` (`:124-126`, orphan accounting); `EFFECT_REQUESTED` event shape (value digest field — coordinated with WP-FN-01's format version).
- **Acceptance criteria**: (1) invocation keys digest canonical **arg values** (WP-FN-01 canonicalization), with the legacy shape hash retained as a secondary diagnostic; changed value → typed `ReplayKeyMismatch`, never a silent stale replay; (2) tasks accept explicit user keys; when replay relies on a positional occurrence index > 0 a structured warning is journaled naming the task and index; (3) on replay completion the engine diffs consulted vs resolved keys: orphaned resolved keys (the H4 signature of drift) produce a journaled `replay-drift` report, and strict mode fails the run on it; (4) an un-keyed conditional whose branches share a shape triggers the S3 guard (runtime assertion in strict mode, warning otherwise); (5) replay of an untouched v2 journal remains byte-stable (no false positives — golden replay corpus).
- **Test requirements**: value-drift replay tests (same shape, different values); inserted-step key-stability tests; orphan-key diff tests; strict/warn mode matrix; golden no-drift corpus.
- **Dependencies**: WP-FN-01 (canonical digests, format version).
- **Size**: M
### WP-FN-05: Execution control — cancellation kills processes, deadlines at dispatch, SIGKILL escalation
- **Objective**: Connect the journal's idea of cancellation/timeouts to the operating system's. Verbatim gaps (R1 §2): H5 — `commitEffectCancellation` writes `EFFECT_CANCELLED` and updates the registry but "nothing signals or kills a live process"; the only `.kill(` sites are hook helpers unreachable from cancellation; no run-scoped AbortSignal/PID registry (`fabric:packages/babysitter-sdk/src/runtime/commitEffectResult.ts:136-183`; `harness/unified/subprocess.ts:131`; `hooks/dispatcher.ts:138,262`); H6 — `DEFAULTS.timeout: 120000` / `nodeTaskTimeout: 15min` are configured and surfaced but no `deadline` exists on `EffectAction` and nothing enforces at dispatch (`config/defaults.ts:64,68`; `cli/commands/configure.ts:147,170`); M5 — hook timeout fires SIGTERM then still waits on `close`, so a child ignoring SIGTERM with open pipes hangs the commit (`hooks/dispatcher.ts:136-139,146-153`, same at `:262`); S5 — spawn sites live in the harness/subprocess layer uncoordinated with SDK cancel (`harness/unified/subprocess.ts:110-140`).
- **Findings closed**: H5, H6, M5, S5.
- **Affected paths**: `packages/babysitter-sdk/src/runtime/commitEffectResult.ts:136-183`; new run-scoped process registry module under `packages/babysitter-sdk/src/runtime/`; `packages/babysitter-sdk/src/harness/unified/subprocess.ts:110-140`; `packages/babysitter-sdk/src/hooks/dispatcher.ts:124-153,262`; `EffectAction` gains a `deadline`; `packages/babysitter-sdk/src/config/defaults.ts:64,68` wiring.
- **Acceptance criteria**: (1) a run-scoped registry tracks every spawned process (process-group) and AbortSignal; `commitEffectCancellation` signals+kills registrants — an e2e cancels a run with three live subprocesses and asserts zero survivors by PID sweep; (2) every effect dispatch derives a deadline from configured timeouts; expiry cancels through the same path and journals `EFFECT_TIMED_OUT` with the configured/elapsed values; (3) hook timeout escalates SIGTERM → grace window → SIGKILL on the detached process group; a child that ignores SIGTERM and holds pipes open cannot hang the commit (regression test is exactly that child); (4) all spawn sites route through the registry (S5) — grep gate: no `spawn(`/`.kill(` in sdk runtime/harness outside the registry module; (5) cancellation interacts idempotently with WP-FN-07's cancel-vs-complete precedence.
- **Test requirements**: orphan-sweep e2e; deadline-expiry unit + journal assertions; SIGTERM-immune child regression; registry grep gate in CI.
- **Dependencies**: WP-FN-07 (shared precedence semantics); consumed by WP-FN-11 (preemption) and WP-FN-14 (pause).
- **Size**: M
### WP-FN-06: Session/effect lifecycle residuals — marker precedence, cross-process locking, liveness cleanup
- **Objective**: Close the session-identity residuals. Verbatim (R1 §2): H7 — the stop-hook still never imports `resolveSessionIdWithMarker`/`resolveAmbientSessionId`, so PID-marker precedence is bypassed and a leaked `AGENT_SESSION_ID` shadows the marker whenever the harness omits the input field (`fabric:packages/babysitter-sdk/src/harness/hooks/stopHookHandler.ts:209-225`, env `:218-220`); H8 — `updateSessionState`'s read-modify-write is lockless (temp-file rename only); two concurrent processes last-writer-win (`session/write.ts:87-116,48-81`; the in-process guard at `:130-159` doesn't cover processes); M6 — a non-terminal run whose owning process died still waits the full `STATE_STALE_MS = 24h`; `runState.processId` liveness is not cross-referenced (`session/cleanup.ts:7,179`); M7 — the PID marker is keyed only by harness ancestor PID, no per-session discriminator (`utils/sessionMarker.ts:49-52`); S2 — `resolveAmbientSessionId(undefined)` returns `process.env.AGENT_SESSION_ID` directly (`session/discovery.ts:36-39`); S4 — the stale-retry against raw env persists (`stopHookHandler.ts:294-296`, INFERRED — R1 §2).
- **Findings closed**: H7, H8, M6, M7, S2, S4.
- **Affected paths**: `packages/babysitter-sdk/src/harness/hooks/stopHookHandler.ts:209-225,294-296`; `packages/babysitter-sdk/src/session/{write.ts,cleanup.ts,discovery.ts}`; `packages/babysitter-sdk/src/utils/sessionMarker.ts:49-52`.
- **Acceptance criteria**: (1) stop-hook resolution order is hook-input → PID-marker → env, implemented by importing the marker resolver (grep gate: `stopHookHandler.ts` imports `resolveSessionIdWithMarker`); a leaked stale `AGENT_SESSION_ID` with a live marker resolves to the marker (regression test is that exact shadow); (2) session read-modify-write is guarded by a cross-process file lock; a two-process contention test (real processes, not workers) shows serialized updates with zero lost writes; (3) cleanup cross-references `runState.processId` liveness: a non-terminal run with a dead owner is reaped promptly (bounded by a liveness-check interval, not 24h) and journaled as `orphaned-run-reaped`; the 24h staleness remains only as the last-resort backstop; (4) PID markers carry a per-session discriminator so descendant processes of one harness ancestor cannot cross-adopt sessions; (5) `resolveAmbientSessionId(undefined)` consults markers before env (S2) and the raw-env stale-retry path is removed (S4).
- **Test requirements**: shadow-env regression; multi-process lock contention; dead-owner reap test with fake PID; descendant-collision test; discovery-order unit tests.
- **Dependencies**: none upstream; hardens the session substrate the migrated observe lane keeps using (WP-T3-15).
- **Size**: M
### WP-FN-07: Parallel/async semantics — result alignment, error aggregation, incarnation guards, scoped rejection capture
- **Objective**: Fix the parallel/async correctness cluster. Verbatim (R1 §2): M1 — the losing committer of a cancel-vs-complete race gets a thrown `RunFailedError`, not an idempotent typed no-op; no precedence defined (`fabric:packages/babysitter-sdk/src/runtime/commitEffectResult.ts:35-38,147-149`); M2 — bounded parallel filters `slot.value !== undefined`, so a branch legitimately resolving `undefined` vanishes and positions shift; the first non-pending error discards sibling pendings (`runtime/intrinsics/parallel.ts:132-137,128-129`); M3 — `allOrNothing` throws only `errors[0]`; `firstSuccess` treats an `undefined` result as failure (`runtime/parallelStrategies.ts:28-30,64,75-78`); M4 — background effect records carry no run-incarnation token and nothing rebuilds group state from the journal (`runtime/asyncEffects.ts:78-94`); S1 — `unhandledRejection` capture is process-global, not run-scoped (`runtime/orchestrateIteration.ts:86-87,215`; ALS exists only for process context, `runtime/processContext.ts:47`).
- **Findings closed**: M1, M2, M3, M4, S1.
- **Affected paths**: `packages/babysitter-sdk/src/runtime/commitEffectResult.ts:35-38,147-149`; `packages/babysitter-sdk/src/runtime/intrinsics/parallel.ts:128-137`; `packages/babysitter-sdk/src/runtime/parallelStrategies.ts:28-78`; `packages/babysitter-sdk/src/runtime/asyncEffects.ts:78-94`; `packages/babysitter-sdk/src/runtime/orchestrateIteration.ts:86-87`; `packages/babysitter-sdk/src/runtime/processContext.ts`.
- **Acceptance criteria**: (1) cancel-vs-complete has documented cancel-wins precedence; the loser receives a typed idempotent no-op result (both orderings tested under the run lock); (2) parallel results preserve position and legitimate `undefined` values (sentinel-based pending tracking, not value filtering); (3) failing strategies throw an `AggregateError` carrying every sibling error; `firstSuccess` accepts `undefined` as success; (4) background commits carry a run-incarnation token; a commit from a stale incarnation is rejected and journaled `stale-incarnation-rejected`; group state is rebuildable from the journal after crash (test: kill mid-group, restart, converge); (5) rejection capture is scoped per run via AsyncLocalStorage — two concurrent runs in one process each capture only their own strays (test is exactly that).
- **Test requirements**: race-order matrix; undefined-preservation and position tests; AggregateError content tests; crash/rebuild incarnation e2e; concurrent-run stray isolation.
- **Dependencies**: WP-FN-05 (shared cancellation path).
- **Size**: M
### WP-FN-08: trust-core human-root requirement in the chain verifier
- **Objective**: Move human-root enforcement into trust-core itself. Residual verbatim (R1 §2 H9): `trust-core/src/chain.ts` has no `requiredRootKind`; human-root checks exist only one layer up (`fabric:packages/adapters/policy/src/proven-bridge.ts:92-119`; `verify-envelope-trusted.ts:253-257`), "so any consumer not going through adapters/policy gets no human-root guarantee".
- **Findings closed**: H9.
- **Affected paths**: `packages/trust-core/src/chain.ts` (verifier options); `packages/adapters/policy/src/proven-bridge.ts:92-119` and `verify-envelope-trusted.ts:253-257` (re-based on the core option); call sites in adapters/policy/tools/transport and genty-core (trust-core dependents per R1 §3.7).
- **Acceptance criteria**: (1) the chain verifier accepts `requiredRootKind` and rejects chains whose root kind mismatches (expired/revoked semantics unchanged); (2) proven-bridge and verify-envelope-trusted delegate to the core option (no duplicated kind logic — grep gate); (3) a consumer calling trust-core directly, bypassing adapters/policy, still gets human-root enforcement when it passes the option — and the migration's new consumers are contractually bound to pass it: drive-lane permission callbacks (WP-T3-17), environment auth (WP-T3-30), relay envelopes (WP-T3-31) each carry an integration test asserting `requiredRootKind: 'human'` where a human gate is claimed; (4) API is plain TS (B4).
- **Test requirements**: kind-mismatch/expiry/revocation matrix in trust-core's suite (8 test files today — R1 §3.7 — this WP grows them); delegation grep gate; the three cross-spec integration assertions land with their owning WP-T3-* but are specified here.
- **Dependencies**: none upstream; feeds WP-FN-02/03 and WP-T3-17/30/31 (§5.3).
- **Size**: S
### WP-FN-09: Memory-system unification — ADR + implementation (kip-sdk / genty local memory / kradle AgentMemory)
- **Objective**: Force and execute the memory ADR. Today three disconnected systems persist (R1 §2 CAP1): kip-sdk's graph repo with **zero** imports anywhere under `packages/genty` (repo-wide grep); genty's `long-term-memory.json` written by the session module and consumed only inside it (`fabric:packages/genty/platform/src/session/memoryExtraction.ts:45-47`, duplicated in `genty/runtime/src/session/memoryExtraction.ts`); kradle's git-backed AgentMemory controllers (`fabric:packages/kradle/core/src/agent-memory-{controller,import,query,repository-source-controller}.js`). **Recommendation (for the ADR to ratify or overturn with evidence): kip-sdk becomes the durable memory backend** — it is the invested asset (7,005-line engine, 114 test files — R1 §3.5), spec 15 already names it `@fabricstack/memory` (§3.2), and the alternatives are a session-local JSON file and a controller family whose storage is git plumbing; genty extraction becomes a write-through client; kradle AgentMemory remains the org-facing control surface re-based on the same backend.
- **Findings closed**: CAP1.
- **Affected paths**: ADR at `docs/adr/memory-unification.md`; `packages/kip-sdk` (consumer-facing API hardening); `packages/genty/platform/src/session/memoryExtraction.ts` + the `genty/runtime` duplicate (deleted — one module remains); `packages/kradle/core/src/agent-memory-*.js` (backend re-base); `packages/genty/platform` gains the memory dependency.
- **Acceptance criteria**: (1) the ADR is committed with the three-way comparison, the chosen architecture, and migration notes for existing `long-term-memory.json` files and AgentMemory git repos; (2) after implementation there is **one write path**: a memory extracted in a genty session is retrievable through the kradle AgentMemory query surface (e2e proves the round-trip); (3) kip-sdk has ≥1 production consumer — the CAP1 grep (`kip-sdk|@a5c-ai/kip` under `packages/genty`, adjusted for post-rename names) is non-zero, inverting R1's finding; (4) the duplicated memoryExtraction module is gone (grep gate); (5) memory reads/writes are attributable (principal recorded) so the trust/audit planes extend to memory.
- **Test requirements**: round-trip e2e (session extract → backend → kradle query); migration fixture tests for both legacy stores; kip-sdk consumer contract tests. CI gating of kip-sdk's full suite is Q-01 (spec 30) and precedes GA of this WP.
- **Dependencies**: WP-FN-15 (the KIP security deferrals become load-bearing once kip is the platform memory — GA-blocking); Q-01 (spec 30); spec 15 §3.2 naming (`@fabricstack/memory`) is independent and non-blocking.
- **Size**: L
### WP-FN-10: Pre-dispatch budget enforcement
- **Objective**: Enforce budgets **before** spend. Today the check lives in `applyPostEffectOrchestrationOverlays` and runs on cost already incurred; over-budget only sets paused-after-the-fact; no `estimateEffectCost`-style guard exists (`fabric:packages/genty/platform/src/harness/internal/createRun/orchestration/effects.ts:661,681,687-695` — R1 §2 CAP2).
- **Findings closed**: CAP2.
- **Affected paths**: `packages/genty/platform/src/harness/internal/createRun/orchestration/effects.ts:661-695`; new pre-dispatch estimator module beside it; cost-record types (`fabric:packages/adapters/core/src/run-handle.ts:9,21-27` — R4 §A.3) as the estimate/actual currency; budget policy config surface.
- **Acceptance criteria**: (1) every cost-bearing effect dispatch passes a pre-dispatch estimate gate; a dispatch whose estimate exceeds remaining budget is refused **before** any provider call, with a typed journaled refusal naming budget, estimate, and remaining; (2) policy is configurable hard (refuse) / soft (journal + allow once) per run and org; (3) the post-hoc check survives as reconciliation — estimate-vs-actual drift is journaled and feeds estimator calibration; (4) estimates improve from real usage: the adopted usage/quota ingestion (WP-T3-33) is consumed as the estimator's data source where available, static model pricing as fallback; (5) over-budget refusal composes with pause semantics (WP-FN-14) rather than killing state.
- **Test requirements**: refusal-before-spend unit tests (provider client mocked, asserted un-called); hard/soft matrix; drift-reconciliation tests; an e2e exhausting a small budget mid-run.
- **Dependencies**: WP-T3-14 (cost records survive the projection re-platform), WP-T3-33 (usage ingestion — soft dependency, fallback specified), WP-FN-14 (pause composition).
- **Size**: M
### WP-FN-11: Campaigns and scheduler-preemption entities
- **Objective**: Build the missing batch/priority layer: zero `campaign`/`Campaign` hits exist in `kradle/core/src`, `kradle/web`, `genty/platform/src`, and no scheduler/preemption entity exists (R1 §2 CAP3). A Campaign is a first-class org-scoped entity that fans out N dispatches under concurrency/priority/budget constraints; the scheduler preempts lower-priority work when capacity is contended.
- **Findings closed**: CAP3.
- **Affected paths**: new `packages/kradle/core/src/campaign-controller.js` + scheduler module beside the existing dispatch path (`fabric:packages/kradle/core/src/agent-dispatch-controller.js` — R4 §B.1); Campaign CRD in `packages/kradle/charts` (K8s CR resource model per R1 §3.2; chart-name rename is WP-RN-12's later sweep); typed API surface via the contracts fabric groups (WP-T3-02) consumed by `packages/kradle/web` (typed per WP-T3-22 — no new untyped routes: the 81-route debt must not grow).
- **Acceptance criteria**: (1) Campaign CR + controller: create a campaign of N tasks with `maxConcurrent`, priority, and a budget reference; reconciliation dispatches, tracks per-item state, and completes/aborts the aggregate; (2) preemption: with capacity saturated, a higher-priority dispatch preempts the lowest-priority running item via pause (WP-FN-14) where the harness supports it, else clean cancellation (WP-FN-05) with requeue — preempted items resume/retry and the journal records the preemption chain; (3) campaign budgets integrate with WP-FN-10 (aggregate pre-dispatch gate across items); (4) the API surface is typed from birth (schema in the contracts fabric groups; grep gate: no new untyped `route.js` under `orgs/[org]/campaigns`); (5) e2e on the deployed stack (publish.yml live e2e slot — R1 §4.2) runs a 5-item campaign with `maxConcurrent: 2` plus one preemption and asserts terminal states + journal provenance for every item.
- **Test requirements**: controller reconcile unit tests; preemption matrix (pause-capable vs cancel-only harness); budget-aggregate tests; deployed-stack e2e.
- **Dependencies**: WP-FN-05, WP-FN-10, WP-FN-14; WP-T3-02 (contracts fabric groups), WP-T3-20 (dispatch controllers become environment clients — the campaign controller targets the post-migration dispatch path, not the retiring direct-drive one).
- **Size**: L
### WP-FN-12: Improvement outer loop — history→eval→compare→promote
- **Objective**: Build the self-improvement loop the platform claims. `kip-sdk/src/learn/` exists (`compile.ts` 242 + `index.ts` 749 lines) but has no incumbent-comparison/promotion logic (zero hits for promote/incumbent) and no consumer orchestrating history→eval→compare→promote (R1 §2 CAP4).
- **Findings closed**: CAP4.
- **Affected paths**: `packages/kip-sdk/src/learn/{compile.ts,index.ts}` (promotion/incumbent logic); new orchestrating process definition in `library/` (the in-repo process library — R1 §3.4; renamed `process-library/` by RN-3, non-blocking); a journal-history reader over `.a5c/runs` (same substrate as the gateway kanban — `fabric:packages/adapters/gateway/src/kanban/lib/source-discovery.ts:12-34`, R4 §B.4.3).
- **Acceptance criteria**: (1) a runnable babysitter process executes the full loop: ingest run history from journals → compile candidate improvements (learn/) → evaluate candidate vs incumbent on a defined eval set → promote or reject with explicit, recorded criteria; (2) promotion is a journaled, signed decision (trust-core envelope — the loop's own provenance is not exempt from WP-FN-02's posture) and is reversible (demote restores the incumbent); (3) `learn/` gains real incumbent-comparison APIs (the CAP4 zero-grep for promote/incumbent inverts); (4) the loop runs end-to-end in CI against a fixture history corpus with a deterministic promote and a deterministic reject; (5) no auto-promotion to production surfaces without a human approval gate (7-action taxonomy `release` action — §5.2).
- **Test requirements**: fixture-corpus loop e2e (promote + reject paths); promotion-record signing/verification tests; demotion test; eval determinism harness.
- **Dependencies**: WP-FN-09 (memory ADR fixes where learn state lives), WP-FN-02 (signed decisions), Q-01 (kip suite gated — spec 30); approval gating via existing `AgentApproval` (`agent-approval-controller.js:15`).
- **Size**: L
### WP-FN-13: Inference scale-to-zero
- **Objective**: Close the CAP5 residual verbatim (R1 §2): virtual-model matching landed on the infer route (`fabric:packages/kradle/web/app/api/orgs/[org]/inference/services/[name]/infer/route.js:36-45`, `bridge.matchVirtualModel` at `:45`) but "scale-to-zero still absent — zero hits for `minScale|knative|scaleToZero` anywhere in `packages/kradle`".
- **Findings closed**: CAP5 (residual).
- **Affected paths**: `packages/kradle/core/src/kradle-inference-service-controller.js` and `virtual-model-controller.js` (R4 §B.3 FABRIC-ONLY row); the infer route `route.js:36-45`; inference service CR schema + `packages/kradle/charts` (deployment knobs).
- **Acceptance criteria**: (1) an inference service with `scaleToZero` enabled and an idle window elapsed scales its replicas to 0 (controller-driven; the CR records the scaled-to-zero condition); (2) an infer request against a scaled-to-zero service triggers wake and is **queued, not dropped**: the route holds/retries within a configurable cold-start budget and returns the inference result, or a typed 503-with-retry-after past budget — never a connection error masquerading as model failure; (3) cold-start wake and idle scale-down are both journaled/metered (duration surfaced for capacity tuning); (4) virtual-model routing composes: a virtual model whose backing service is asleep wakes it transparently; (5) e2e on GKE staging (deploy_kradle path — R1 §4.2): scale-to-zero → cold infer → warm infer, asserting queue-not-drop.
- **Test requirements**: controller idle/wake unit tests with fake clock; route hold/timeout tests; GKE staging e2e.
- **Dependencies**: none on migration (fabric-only plane — R4 §B.4.1); chart changes ride current names (WP-RN-12 renames later).
- **Size**: M
### WP-FN-14: Session pause/resume/fork/rewind wired into the agent loop
- **Objective**: Close the CAP6 residual verbatim (R1 §2): `rewind.ts`/`tree.ts` exist with a CLI export command as their only outside consumer; the loop has a `'paused'` status string (`fabric:packages/genty/core/src/loop/types.ts:97`) but **zero** pause handling in `agent-loop.ts`; "snapshot-at-step-boundaries / mid-loop pause+persist / resume-context restoration remain unimplemented".
- **Findings closed**: CAP6 (residual).
- **Affected paths**: `packages/genty/core/src/loop/agent-loop.ts` + `loop/types.ts:97`; `packages/genty/runtime/src/session/{rewind.ts,tree.ts}` (promoted from orphan to loop-integrated); session snapshot persistence in `packages/genty/runtime`; control-surface exposure via the contracts fabric groups (WP-T3-02) so pause/resume/fork/rewind are operator actions, not CLI-export archaeology.
- **Acceptance criteria**: (1) pause: at the next step boundary the loop persists a resumable snapshot (messages, tool state, memory refs) and transitions to `paused` — the status string finally has semantics; (2) resume: a paused session resumes with restored context and produces a coherent next turn (e2e: pause mid-multi-step task, resume, task completes); (3) fork/rewind: a session can be forked at a prior tree node and rewound to one, via the control surface; where the driving harness supports conversation rollback the lane capability is used, else fabric-side replay-from-snapshot (capability flag consulted, per the `ProviderAdapter` capability model — WP-T3-05); (4) pause composes with preemption (WP-FN-11) and budget-pause (WP-FN-10) — one pause mechanism, three callers; (5) every transition is journaled with provenance (run identity stays in the babysitter journal — §5.1).
- **Test requirements**: pause/resume e2e across a step boundary; fork divergence test (two branches, independent completions); rewind-then-continue test; capability-flag fallback matrix (rollback-capable vs not); journal-provenance assertions.
- **Dependencies**: WP-FN-05 (suspension of live processes), WP-T3-05 (capability flags), WP-T3-23 (checkpoint/approval coordination — genty rewind must not fight environment checkpoints: the environment owns workspace checkpoints, genty owns conversation state; the boundary test lands here).
- **Size**: L
### WP-FN-15: KIP security completion — KeyAuthorization chain, manifest CID, durability tiers
- **Objective**: Implement the three security TODOs verbatim at `fabric:packages/kip-sdk/src/kip-repo.ts:4063-4075` (R1 §2 KIP-TODO): genesis-manifest CID re-verification ("not implemented", reported `true` unconditionally); KeyAuthorization authority checking (`authorityViolations: []` hardcoded); durability tiers (empty arrays).
- **Findings closed**: KIP-TODO.
- **Affected paths**: `packages/kip-sdk/src/kip-repo.ts:4063-4075` and the verification/authority modules it delegates to; kip-sdk test tree (`src/__tests__/`).
- **Acceptance criteria**: (1) genesis-manifest CID re-verification is real: a repo whose genesis manifest was substituted fails verification (the unconditional `true` is gone); (2) KeyAuthorization chains are actually checked: an operation signed by a key outside its authorized scope produces a populated `authorityViolations` report and is rejected; (3) durability tiers are implemented per their M6/M9 design notes with tier state reported truthfully (no hardcoded empty arrays); (4) the M6/M9 deferred-work markers at `kip-repo.ts:4063-4075` are gone — a grep gate on those upstream marker strings returns zero hits; (5) the new behavior is exercised by the full kip suite, whose CI gating is Q-01.
- **Test requirements**: substituted-genesis negative test; out-of-scope-key negative test; durability tier state-machine tests; grep gate in CI.
- **Dependencies**: none upstream; **blocks GA of WP-FN-09** (memory backend must not ship with hardcoded-green security checks).
- **Size**: M
### WP-FN-16: Hosted remote access — coverage acceptance for the four-route story (D12)
- **Objective**: Own the D12 guaranteed gap at the platform level: verify that the four remote-access routes (§4 FR-1…FR-7) exist, compose with fabric's org/trust/journal planes, and are provable by e2e — the mechanics are built by WP-T3-28 (ssh), WP-T3-29 (tailscale), WP-T3-30 (DPoP pairing/auth), WP-T3-31 (relay), WP-T3-24 (client connection catalog); this WP is their coverage-side integration and acceptance owner, starting from fabric's confirmed zero (R1 §3.10).
- **Findings closed**: none from the register (D12 guaranteed gap — mandated regardless of findings).
- **Affected paths**: integration/e2e assets only (no new product code of its own): `e2e-tests/` remote-access suites; runbook `docs/remote-access-runbook.md`; assertions over the surfaces landed by WP-T3-28…31 (`packages/ssh`, `packages/tailscale`, environment auth in `apps/environment`, `infra/relay` — spec 10 §2 rows 4/5/6/10, under spec 15 §3.3 names from birth).
- **Acceptance criteria**: (1) **FR-1**: each of the four routes reaches the same environment contracts-RPC surface and completes an authenticated run-dispatch round-trip in e2e; (2) **FR-2**: the relay e2e asserts broker-not-proxy — post-bootstrap traffic bypasses the relay, and session tokens are absent from relay-side captures/logs; (3) **FR-3**: cross-org access via relay is denied and audited (two-org fixture); identity resolves through kradle org identity, no Clerk artifact anywhere (grep gate); (4) **FR-4**: relay envelope verification calls trust-core with `requiredRootKind` per WP-FN-08 (one PKI — grep gate: no `@noble/curves` verification path outside trust-core wrappers); (5) **FR-5**: pairing from console surfaces issues DPoP-bound grants; the legacy short-code path is gone (`short-code.ts` deleted by WP-T3-30 — asserted); (6) **FR-6**: a remotely-driven run's journal, approvals, and attestation records are byte-equivalent in kind to a local run's (differential e2e); (7) **FR-7**: the relay runbook exists and a staging relay deployment executes it (packaging/rollout owned by specs 40/50).
- **Test requirements**: four-route e2e matrix (LAN, tailscale, ssh, relay) each with dispatch + journal assertions; relay token-absence capture test; two-org denial test; local-vs-remote differential journal test. These suites feed Q-04's whole-platform lane (spec 30).
- **Dependencies**: WP-T3-24, WP-T3-28, WP-T3-29, WP-T3-30, WP-T3-31; WP-FN-08; Q-04 (spec 30) consumes its suites.
- **Size**: L
### WP-FN-17: Commander disposition — wire to a live backend (recommendation: WIRE)
- **Objective**: Resolve the largest fully-orphaned functional surface (R1 §3.9): `apps/commander` runs entirely on a mocked, seeded backend by design, with `SPEC-LIVE-BACKEND.md` as the unbuilt plan and zero workflow references. **Recommendation: WIRE, not descope** — the board is contracts-complete with 51 test files and real operator value; the descope alternative (formal retirement + archive) is recorded as the fallback if Gate B overturns. Wiring is **retargeted**: `SPEC-LIVE-BACKEND.md` was written against gateway protocol v1 (`apps/commander/src/contracts/gateway-protocol.ts` mirrors the 17 frames), but WP-T3-21 folds those frames into contracts RPC — RealBackend therefore implements the `CommanderBackend` interface (8 methods, `src/backend/types.ts`) over the **contracts RPC surface**, using WP-T3-21's frame↔RPC mapping table as the translation source and inheriting SPEC-LIVE-BACKEND's documented v1-protocol gaps (board verbs, release/editor verbs, `hook.decision.optionId`) as fabric-group schema additions (WP-T3-02).
- **Findings closed**: none from the register (newly-found orphan O1).
- **Affected paths**: `apps/commander/src/backend/` (new `RealBackend` beside `mock/mockBackend.ts`, which stays byte-identical and default per SPEC-LIVE-BACKEND); `apps/commander/src/contracts/gateway-protocol.ts` (superseded by contracts imports for the real path; the frozen mirror stays for the mock — spec 10 §7 notes commander consumes frozen mirrors, not live imports); `apps/commander/src/App.tsx` boot seam (lines 91/93/170/184 per SPEC-LIVE-BACKEND §0); contracts fabric groups for the three gap verbs (rides WP-T3-02).
- **Acceptance criteria**: (1) `RealBackend` implements all 8 `CommanderBackend` methods against a live environment's contracts RPC; mock remains the default boot path, real selected only by explicit config; (2) live e2e: against a real deployed stack, a dispatched run appears on the board, its hook request surfaces, and an operator decision round-trips to the run (the approval plane §5.2 is exercised, not simulated); (3) the three documented v1 gaps are closed by typed fabric-group schemas, not ad-hoc frames; (4) the UI is not modified (SPEC-LIVE-BACKEND scope rule — diff gate on `src/` outside `backend/` + the boot seam); (5) disposition record committed; if Gate B chooses descope instead, the alternative acceptance is: retirement ADR + removal from the workspace + WP-RN-05's matrix updated (spec 15 §3.2 renames it `@fabricstack/ops-console`; rename and disposition are independent, per that row).
- **Test requirements**: RealBackend contract tests mirroring the mock's suite; live board e2e (dispatch → board → decision); frame↔RPC translation goldens shared with Q-09 (spec 30). CI gating of commander's existing 51-file suite is Q-01/Q-05.
- **Dependencies**: WP-T3-02, WP-T3-21; Q-05 (UI e2e gating).
- **Size**: L
### WP-FN-18: Harness matrix remediation — red lanes to green, Grok coverage
- **Objective**: Bring the D7(a) six-harness set to functional green. Status at HEAD (R1 §4.3): Claude Code GREEN, Codex GREEN, **Cursor failing (#562)**, **OpenCode skipped/failing**, **Antigravity failing (#945**, active churn — HEAD~7 `18e5a7de8` fixed antigravity hook mappings), **Grok Build entirely unsupported (no adapter, no lane** — R1 §3.1). The fixes are *delivered by* the migration lanes — Cursor WP-T3-07, Grok WP-T3-08, Antigravity WP-T3-09, OpenCode WP-T3-12 — this WP owns the **coverage outcome**: the lanes actually turn green in the live matrix, the tracked issues close with root-cause notes, and the matrix reflects reality. Division vs spec 30: Q-03 owns the e2e *matrix infrastructure and gating*; WP-FN-18 owns the *functional remediation* asserted through it.
- **Findings closed**: none from the register (dossier-found red-lane cluster).
- **Affected paths**: `.github/workflows/live-stack.yml` agent map (14 ids today, no grok — R1 §3.1/§4.3); `MATURITY-MATRIX.md` per-agent rows (2026-08-13, stale); issues #562/#945 closure notes; lane code itself belongs to WP-T3-07/08/09/12.
- **Acceptance criteria**: (1) live-stack lanes for Claude Code, Codex, Cursor, Grok Build, OpenCode, Antigravity pass on the push-default and full-matrix modes with per-lane artifacts asserted (`adapters-events`, `transport-adapter-trace`, `provider-trace-redacted`, trace ids — R1 §4.3); (2) `grok` exists in the agent map and its lane is green (net-new — closes the R1 §3.1 zero-hit finding); (3) #562 and #945 are closed with root-cause notes linking the fixing WP; (4) `MATURITY-MATRIX.md` per-agent rows are refreshed to post-migration reality with workflow-line evidence; (5) three consecutive scheduled matrix runs green (not a single lucky pass) before the WP closes.
- **Test requirements**: the live-stack matrix itself (Q-03 gates it); lane-artifact assertions; a red-lane quarantine rule (a newly-red lane files an issue automatically — rides the existing failure-triage workflow, `failure-triage-live-stack.yml` — R1 §4.3).
- **Dependencies**: WP-T3-06…13 (lanes), WP-T3-15 (observe rebind), Q-03 (spec 30).
- **Size**: M
### WP-FN-19: Agent-layer gap absorption — the 47-item corpus by category
- **Objective**: Close or disposition every item in `docs/agent-layer-gaps.md` (47 agent-core gaps + runtime/platform/adapter sections — R1 §5). The Critical/High core set is implemented outright: no streaming (`prompt()` waits for full response, single `text_delta` — `session.ts:200-257`), no multi-turn history (messages rebuilt each call — `session.ts:217-223`), token usage discarded (parsed, never returned — `session.ts:163-177`), no tool AbortSignal (`types.ts:86-96`), `initialize()` no-op (`session.ts:196-198`), no DI for the LLM client (`session.ts:40-97`), fragile browser tool (global singleton — `agenticTools/browser/tool.ts`), hardcoded web search (`agenticTools/web/tools.ts:47-54`), no typed tool errors (`agenticTools/shared/results.ts`), concatenation-as-summary (`context/strategies/summary.ts:18-39`) — file paths per the corpus, rooted at `packages/genty/core/src/`. These land in genty-core, which **survives the migration as fabric's own runtime** (agent-runtime-core, B4 plain TS — spec 15 §3.1 row 35; t3code replaces shells and drive lanes, not this engine). This WP also owns the **item-level disposition table** across both fine-grained corpora (§3.3): all 47 agent-layer items plus the 149 `docs/harness-features-backlog/gaps/` files, each routed to an owning WP or explicitly descoped with a reason — and re-verifies any `genty-features-backlog-updated` CLOSED claim it touches.
- **Findings closed**: none from the register (pre-existing corpus, absorbed per R1 spec input 15).
- **Affected paths**: `packages/genty/core/src/session.ts:40-257`, `types.ts:86-96`, `agenticTools/{browser/tool.ts,web/tools.ts,shared/results.ts}`, `context/strategies/summary.ts:18-39`, `context/token-estimator.ts`; disposition table at `docs/specs/platform-gaps/agent-layer-disposition.md`.
- **Acceptance criteria**: (1) streaming: token-by-token deltas exposed through the session API and visible on the projection (`AgentEvent` message deltas — the 49-type union's delta events, `fabric:packages/adapters/core/src/events.ts:85-115` per R4 §A.1, finally fed by genty's own runtime); (2) multi-turn history: persistent conversation context across `prompt()` calls with an explicit reset API; (3) token usage returned to callers and accumulated per session — and flows into WP-FN-10's estimator; (4) custom tools receive AbortSignal and honor cancellation (composes with WP-FN-05); (5) typed tool error taxonomy replaces string-only errors; (6) LLM client injectable (DI seam) — unit tests run against a fake client without network; (7) browser/web tools: pooled, resource-limited, pluggable backend (or category-descoped with reason in the table — allowed outcome); (8) real summarization strategy replaces concatenation, or the strategy is renamed/descoped honestly; (9) the disposition table covers 47 + 149 items with zero unrouted rows.
- **Test requirements**: streaming/multi-turn/usage unit + integration tests against the fake client; AbortSignal cancellation tests; error-taxonomy tests; disposition-table completeness check (script-verified row count) in docs-quality CI.
- **Dependencies**: WP-FN-05 (cancellation), WP-FN-10 (usage feed); coordinates with WP-T3-14 (delta events ride the projection).
- **Size**: L
### WP-FN-20: Hardcoded-literals → catalog graph backlog (~201 literals)
- **Objective**: Retire the standing atlas-adoption debt: ~201 hardcoded harness-specific literals in production code that should derive from the atlas graph (`docs/hard-coded-and-should-be-in-graph-gaps-backlog.md` — R1 §3.6/§5), by category: adapter self-identity defaults (38, High), self-registration calls (10, High), hooks-adapter defaults+fallbacks (40, High), dispatch switches (11), class→format maps (9), SDK prompt-context factory names (9), CLI paths/capabilities (5), model/host-detection registries (6), CJS process scripts (18, Low); harness-mock's 55 test refs are excluded by the backlog itself.
- **Findings closed**: none from the register (pre-existing corpus).
- **Affected paths**: `packages/adapters/{codecs,core,cli,extensions,hooks/*}` literal sites per the backlog's per-category listings; the atlas→agent-catalog bridge (backlog's stated data flow); `packages/atlas` graph entries where missing; backlog doc updated to a residual allowlist.
- **Acceptance criteria**: (1) the three High categories (88 refs — identity defaults, registration calls, hooks defaults/fallbacks) derive from the atlas bridge; grep of the enumerated literals in those categories returns only the bridge/fixture sites; (2) Medium categories (dispatch switches, format maps, factory names, CLI capabilities, detection registries — 40 refs) derive likewise or carry a per-site justification in the residual allowlist; (3) the Low CJS-script category (18) is dispositioned (derive or allowlist) — an allowlist is acceptable there; (4) a CI guard fails on new hardcoded harness literals outside the allowlist (the same guard WP-T3-33's AC(5) requires for new lanes — one guard, both consumers); (5) sequencing safety: literal migration in a codec lands only after that codec's lane disposition (WP-T3-13's table) so no literal is migrated twice or into retiring code.
- **Test requirements**: bridge-derivation unit tests per category; the CI literal guard with a violating fixture; post-migration grep audit reproducing the backlog's counting method with residual ≤ allowlist.
- **Dependencies**: WP-T3-13 (codec disposition order), WP-T3-33 (atlas-fed model manifest + shared guard); atlas tests gated by Q-01 (spec 30).
- **Size**: L
### WP-FN-21: Realtime media plane — from live-pending to live-proven
- **Objective**: Close the realtime harness residuals (`docs/research/realtime-agent-gaps.md` — R1 §3.2/§5): control plane is real (dispatch, sidecar, CRDs, meeting MCP tools; meeting-dispatch software path PROVEN LIVE per G0-RT), but the production path still publishes Chrome's fake-device stream, and the implemented media stack (G1 avatar render, G2 canvas video publish, G3 TTS audio, G4 lipsync — all "DONE (impl) · live-publish pending") has never published into a live room. Named residuals from the register: cluster capacity (pod `Pending`, `Insufficient cpu`), the custom `kradle-jitsi.<payload>.<sig>` JWT format prosody may reject, JVB UDP media (X2), real TTS provider credentials, real-GPU avatar quality. **Recommendation: WIRE** to live-proven for join+publish+lipsync; the real-GPU TalkingHead quality tier is the one staged-descope candidate (explicitly allowed to remain a documented residual).
- **Findings closed**: none from the register (pre-existing corpus).
- **Affected paths**: `packages/kradle/jitsi-agent-sidecar/src/` (`puppeteer-jitsi-client`, `browser/{avatar,compositor,publish-effect,lipsync}.js`, `audio.js`, `ipc-client.js`); JWT signing in the controller path (`jitsi-agent-bridge.js` region per the register); `scripts/g0-rt-jitsi-e2e.sh` + `.github/workflows/g0-rt-jitsi-e2e.yml`; new capacity pre-flight `scripts/g0-rt-preflight-capacity.sh` (first step of the e2e workflow); the staging cluster's agent node pool (provisioning item **OPS-FN-21a** in Dependencies — a deliverable of this WP with a named owner surface and verification command, not an unowned ops note).
- **Acceptance criteria**: (1) the g0-rt e2e dispatches a video agent that **joins a live room and publishes real video + audio tracks** (not `--use-fake-device-for-media-stream`), asserted from a second participant's receive side; (2) the meeting JWT is accepted by prosody (standard-format or prosody-side verifier — the format decision is recorded; the custom-format rejection risk named in the register is closed either way); (3) lipsync runs on the live published track (a lipsync fault surfaces as an error, never a silent tone — the register's no-silent-fallback rule preserved); (4) TTS provider is pluggable with the mock default and at least one real provider verified in the live e2e (credentials via kradle secrets grants, not env baking); (5) the e2e is repeatable in CI (the standalone workflow) and its capacity prerequisite is encoded as the OPS-FN-21a pre-flight check (`scripts/g0-rt-preflight-capacity.sh`, first step of `g0-rt-jitsi-e2e.yml`): a canary pod carrying the sidecar Job's exact CPU/memory requests must bind within the check's timeout, else the check fails with a node-by-node allocatable report — an actionable failure message rather than a scheduling mystery; this same check green on the target cluster is what discharges the roadmap's Phase-5 entry prerequisite (`50-roadmap-workpackages.md` §5 Phase 5 entry prerequisites, §3 note 10); (6) any descoped tier (GPU avatar quality) is listed in the register doc as descoped-with-reason, not left "pending".
- **Test requirements**: receive-side track assertions (kind, non-blank frames, audio energy); JWT acceptance test against prosody; sidecar unit suites stay green (`runtime.test.js`, `ipc-client.test.js` — AF_UNIX on Linux CI per the register); OPS-FN-21a red-until-green demonstration (pre-flight red on the under-provisioned pool, green after the node-pool change — both runs linked in the closing note, same discipline as spec 15 WP-RN-04 / spec 40 WP-PKG-13 guards); scheduled re-run cadence to catch media-stack drift.
- **Dependencies**: **OPS-FN-21a — staging-cluster node headroom (owned provisioning item of this WP, in the WP-RN-03/WP-PKG-13 GCP-provisioning style — an executed deliverable, not a hand-off to an unnamed ops backlog)**. The register's live blocker verbatim: agent pod `Pending`/`FailedScheduling`, `0/4 nodes available: Insufficient cpu` — the control plane + in-cluster Jitsi stack consume the node headroom (`docs/research/realtime-agent-gaps.md` G0-RT). *Owner surface*: the agent node pool of the cluster the kradle staging deploy lane targets at execution time — AKS `kradle-staging` at register time, its GKE successor if the control plane has moved by then (R1 §4.2 `deploy_kradle` path is the pointer of record). *Execution*: the node-pool sizing change is the first tracked deliverable of whoever lands WP-FN-21 — committed IaC/pipeline values where the pool is declared, else the recorded scale command (`az aks nodepool scale …` / `gcloud container clusters resize …`) plus before/after `kubectl describe nodes` allocatable capture, recorded in the WP's closing note (WP-RN-04 AC7 discipline). *Verification command*: `scripts/g0-rt-preflight-capacity.sh` (AC5) green on the target cluster, then `gh workflow run g0-rt-jitsi-e2e.yml --ref staging` schedules the pod — the register's stated unblock, reproduced exactly. *Phase-5 entry tie*: the roadmap's Phase-5 entry prerequisite (`50-roadmap-workpackages.md` §5, per §3 note 10) is discharged only by that pre-flight check green — sequencing/entry-criterion ownership stays with WP-RM-01, execution accountability lives here. Other dependencies: kradle deploy lanes (R1 §4.2); no WP-T3-* dependency (fabric-only plane — R4 §B.4).
- **Size**: L
### WP-FN-22: Secret redaction in the general logging layer
- **Objective**: Close the HYG1 residual verbatim (R1 §2): partial mitigations exist (task env-var redaction `fabric:packages/babysitter-sdk/src/tasks/kinds/index.ts:257-268,64-65`; CLI payload redaction behind `BABYSITTER_ALLOW_SECRET_LOGS`, `cli/main/taskCommands.ts:365`; transport passthrough-header redaction `adapters/transport/src/server.ts:525-550`; live-stack asserts a `provider-trace-redacted` artifact) but "the general logging layer `packages/adapters/observability/src/logger.ts` / `logger-simple.ts` still has **zero** redact/scrub/mask logic".
- **Findings closed**: HYG1 (residual).
- **Affected paths**: `packages/adapters/observability/src/{logger.ts,logger-simple.ts}`; a shared redaction module (single implementation the existing partial sites converge on — no fourth bespoke redactor); registration seam for known-secret values (env-derived + config-declared secrets).
- **Acceptance criteria**: (1) the general logger redacts by default: pattern classes (bearer/API-key/PEM/JWT shapes) plus a registry of known secret values; fixture secrets in message, args, and error-cause positions all emerge masked; (2) the pre-existing partial redactors delegate to the shared module (grep gate: one redaction implementation); (3) opt-out remains explicit and loud (`BABYSITTER_ALLOW_SECRET_LOGS` semantics preserved, journaled when active); (4) the live-stack redaction assertion extends beyond provider traces to a general-log sample artifact; (5) redaction failures fail closed (a throwing redactor suppresses the log line, never emits raw).
- **Test requirements**: fixture-secret matrix (positions × pattern classes × value-registry hits); delegation grep gate; fail-closed unit test; extended live-stack artifact assertion.
- **Dependencies**: none; new lanes/environment logs from spec 10 adopt the same module (stated as a WP-T3-19 integration note, enforced by the live-stack assertion).
- **Size**: S
### WP-FN-23: Hygiene closure — duplicate-task-id CI scan, company-repo colon paths
- **Objective**: Close the two surviving hygiene findings (R1 §2): HYG3 — `DuplicateTaskIdError` exists and throws on re-register (`fabric:packages/babysitter-sdk/src/tasks/registry.ts:39-44,50-52`) but no build-time duplicate-id scan runs in CI, so the footgun fires at runtime; HYG4 — the company repo still tracks Windows-invalid colon-path blobs (`git -C C:/work/company ls-files` shows `docs/LinkedinConnections/Beni/Beni - Connections 1:2.csv` and `…2:2.csv`) that cannot be checked out on Windows.
- **Findings closed**: HYG3, HYG4.
- **Affected paths**: new scan script under `scripts/` + a `ci.yml` step (fabric — job map at R1 spec input 13); company repo (`C:/work/company`) git index + a path-guard hook/CI check there. **D17 note**: the company repo is the private planning repo, not the public `a5c-ai/babysitter` repo — the public-repo invariant is untouched.
- **Acceptance criteria**: (1) a build-time scan enumerates registered task ids across the workspace and fails CI on duplicates (fixture with a deliberate duplicate proves the failure; current tree passes); (2) the scan is wired into `ci.yml`'s test job so PRs are gated; (3) the two colon-named blobs are removed from the company repo index (history untouched — index/worktree fix only), a fresh `git checkout` on Windows completes with zero skipped paths; (4) a guard (pre-commit or CI) rejects newly added paths containing characters invalid on Windows (`:*?"<>|`) in the company repo.
- **Test requirements**: duplicate-fixture CI negative test; Windows checkout verification (the HYG4 reproduction inverted); path-guard negative test.
- **Dependencies**: none.
- **Size**: S
### WP-FN-24: `adapters/proxy` (Python) disposition — recommendation: DESCOPE
- **Objective**: Disposition the one orphan no spec claims (§3.2): `adapters/proxy` is a separate Python package with its own pyproject/Docker, outside the TS test lattice (R1 §3.1), functionally shadowed by the TS model proxy `packages/adapters/transport` — which carries the attestation seam (`server.ts:1596-1607` — R1 §2 H10) and is the named model gateway of record (spec 15 §3.1 row 19, `@fabricstack/model-gateway`). **Recommendation: DESCOPE (retire)** — one model-proxy plane, the attested one. The wire alternative is specified for completeness: if implementation research finds a production consumer (deployment manifest, chart reference, or runbook dependency), the package instead gets a CI job, an owner, a §3.3-style name from spec 15, and a capability statement distinguishing it from the transport adapter.
- **Findings closed**: none from the register (newly-found orphan O6).
- **Affected paths**: `packages/adapters/proxy/` (pyproject/Docker tree — R1 §3.1); repo-wide consumer search (charts, workflows, compose files) as the disposition evidence base; disposition ADR at `docs/adr/adapters-proxy-disposition.md`.
- **Acceptance criteria**: (1) the consumer search is executed and recorded in the ADR (grep/manifest audit across `packages/kradle/charts`, `.github/workflows`, deployment docs); (2) **retire path** (default): the tree is removed, no chart/workflow references dangle (grep gate), and any unique capability it had is either confirmed absent or noted as a transport-adapter backlog item; (3) **wire path** (only on found consumer): CI job runs its test suite, Docker build is gated, and the package joins the rename matrix by a spec 15 amendment; (4) either way, exactly one model-proxy plane remains authoritative for attestation (the transport adapter) — asserted in the ADR.
- **Test requirements**: dangling-reference grep gate post-removal (retire path) or CI suite + build gate (wire path).
- **Dependencies**: none; informs WP-RN-05/RN-13 completeness checks (spec 15) either way.
- **Size**: S
---
## 8. Cross-spec obligations honored (D21 checklist)
- **No WP touches the public repo** (D17 / intent acceptance criterion 7); WP-FN-23's company-repo item is explicitly out-of-public-repo (§7 WP-FN-23 note). No WP publishes anywhere but the Artifact Registry pipelines (D19); no new packages are minted here, so no new registry surface appears.
- **Current names / rename independence** (spec 15 interaction rule 3): every affected path above is a current-name path; the only naming interactions are informational (WP-FN-09 ↔ `@fabricstack/memory`, WP-FN-17 ↔ `@fabricstack/ops-console`, WP-FN-24 ↔ spec 15 amendment on the wire path) and none block RN phases or are blocked by them.
- **Spec 10 cross-refs**: F-16 ↔ WP-T3-24/28/29/30/31 (mechanics there, coverage acceptance here); F-18 ↔ WP-T3-07/08/09/12 (lanes there, green-outcome here); F-17 retargets SPEC-LIVE-BACKEND onto WP-T3-02/21's surface; §5 planes bind WP-FN-01/02/03/08 to WP-T3-16/17/23/30/31.
- **Spec 30 cross-refs**: TEST1→Q-01, TEST2→Q-08 per the register (§2); WP-FN-01's tamper suite is Q-08's substrate; WP-FN-16's suites feed Q-04; WP-FN-17/18 gating rides Q-01/Q-03/Q-05.
- **Spec 40 cross-refs**: HYG2→P-01/P-02 per the register (§2); WP-FN-02/03 key provisioning lands with P-04; WP-FN-16 FR-7 relay ops rides P-* rollout.
- **Register completeness (D8)**: all 40 survivor IDs mapped exactly once (§2 table: 37 in WP-FN-* + 3 in sibling WPs); every CHANGED ID's WP objective is the R1 §2 residual verbatim.
Work-package count in this spec: **24** (WP-FN-01 … WP-FN-24; 23 planned + 1 justified addition per §3.2).
documents
[]
Outgoing edges
None.
Incoming edges
contains_page1
- page:docs·PageBabysitter Docs