# Module deepenings — five internal refactors + web data path

status: PROPOSED
task IDs: (none assigned)
source request: 2026-08-13 owner: "create a full spec and plan for all of your recommendations, do not continue to execution yet" — deliverable is documents only; launch is explicit owner-gated.

## Goal

Land six self-contained deepenings: fleet digest/transport capabilities (C8/C19), gptbridge single conversation model + explicit seat factory (C9/C17), systray router and indicator splits (C13/C16), controller store split + verb locality (C10), collector actions gateway table (C11), web single fetch adapter (C15). Owner decision: docs only for now — plan registered PROPOSED, not launched.

## Source design

Normative: docs/specs/2026-08-13-arch-module-deepenings-design.md (§3.1-3.6, §4, §5, §6, §8). This plan adds execution order and file pins only; it MUST NOT contradict the spec.

## Context

- Every claim below verified at origin/main (worktree): all factual pins are in the spec's "Current state" blocks with file:line.
- Dependencies: section 3.6 (web) requires `@overdeck/incident-contract` (plan 2026-08-13-arch-shared-contracts.md). Section 3.4 (controller verb move) requires shared-contracts D6 (the offload-verb import). All other sections are independent and may run in any order or in parallel.
- Fleet delegation path is currently UNTESTED (engine.test.mjs:575 passes a local transport); the delivery MUST add the failure-propagation test (spec §6.3.1) — the old sync-branch silent success must become impossible.
- Unknown-verb fallback in the actions gateway is an explicit `Partial<Record<...>>` + gate (spec 3.5): journaling MUST NOT double-run.

## Files

- 3.1 fleet: NEW lib/fleet/digest.mjs; transport-ssh.mjs (+delegatedAudit/delegatedConverge), transport-local.mjs (+no-op capabilities); engine.mjs (capability dispatch, buildSeatCfg removal), expand.mjs/harden.mjs/loader.mjs (digest imports); NEW modules/fleet/test/delegation.test.mjs.
- 3.2 gptbridge: registry.py (canonical Conversation), translate.py (adapters), convlog.py (persist from registry), solwebd.py (SeatPool.borrow/plain constructor, no cls.__new__).
- 3.3 systray: NEW modules/systray/commands/*.py (per-command handler modules + COMMANDS table), command_router.py (router only), NEW modules/systray/services/*.py, indicator.py (view + events only).
- 3.4 controller: NEW controller/src/leases.ts (+ cluster snapshot + delivery reconcile modules per spec), transitions.ts (owns TRANSITION_VERBS union + VerbSchema), store.ts (verb import + extraction), events.ts (import update).
- 3.5 collector: actions.ts (ACTION_HANDLERS table, schemas verbatim), collector/src/actions.test.ts (unchanged suite must pass).
- 3.6 web: collector-client.ts (artifact-download fetch moves in), collector-queries.ts (new hook), AttemptDetailDrawer.tsx:97 + FactoryTraceTables.tsx:75 (call the hook), mappers untouched.

## Contracts

Per spec §6:

- 3.1: `grep -rc "function sha256Hex" lib/fleet/` = 1; `grep -c "transport.name" lib/fleet/engine.mjs` = 0; new mocked-ssh failure test green.
- 3.2: no `cls.__new__` in solwebd.py.
- 3.3: command names/args/permissions identical; CLI entry points identical.
- 3.4: transitions.ts must not import from store.ts; store.test.ts + transitions.test.ts stay green.
- 3.5: response bodies/statuses/journal entries byte-identical; actions.test.ts green.
- 3.6: `grep -rn "fetch(" apps/web/src/components/ | grep -vE "collector-client|useQuery|useMutation|useInfiniteQuery|refetch"` = empty.

## Behavior

Per spec §4. No user-visible behavior change anywhere; audit report format unchanged; systray command behavior unchanged; honest-data rule applies to web.

## Out of scope

- The shared-contracts package itself (its own plan).
- The already-landed candidates (C1, C2, C6, C14, C20).
- collector-types.ts protocol mirror (shared-contracts §7).
- modules/harness/**, packaging/**; the mandatory factory pytest suite.
- UI restyling, new primitives, gptbridge model/prompt changes, systray appearance; od-ui-dev governs any apps/web edit.

## Acceptance criteria

Per spec §6, all of:

- 3.1: `bun test modules/fleet/test/` (+ new delegation failure test) green; deletion greps pass.
- 3.2: `python3 -m pytest modules/gptbridge/tests/ -q` green.
- 3.3: `python3 -m pytest modules/systray/tests/ -q` green (interactive tiers not required).
- 3.4: `bun test` in controller/ + `tsc --noEmit` green.
- 3.5: `bun test` in collector/ + `tsc --noEmit` green.
- 3.6: `pnpm --filter web build` + `pnpm --filter web typecheck` green; web lib tests green; fetch deletion grep passes.

## Preserved WIP

- Worktree /home/user/Projects/overdeck/.worktrees/arch-deepening (branch wt/arch-deepening at 7158544cf = origin/main). Main checkout is STALE — never the implementation base.
- Review report: /home/user/.cache/agent-tmp/architecture-review-20260813-102418.html (baseline note: 5 candidates already landed at origin/main; do not re-specify).

## Constraints

- Delivery scope is documentation only until the owner lifts it: "do not continue to execution yet" (2026-08-13). MUST NOT launch.
- Landing order: 3.4 and 3.6 start only after the shared-contracts plan lands (D6/D3 dependency); the other sections can run in parallel.
- Each extraction is a move, not a rewrite: same state, same errors, same tests passing.

## Execution steps

1. (Owner gate) Owner approves → plan flips ACTIVE/IDLE with named workers.
2. Land shared-contracts first (3.4, 3.6 depend on it); run 3.1/3.2/3.3/3.5 in parallel lanes.
3. Each section: implement → run its acceptance + deletion tests → land via .claude/scripts/ship.sh → deploy via packaging/deploy-local.sh.
4. Register ADR-0004..0007 files in docs/adr/ (owner-visible records; directory created by plan 2026-08-13-arch-domain-glossary.md).

## Current receipt

2026-08-13: Spec 2026-08-13-arch-module-deepenings-design.md written in worktree, externally reviewed (APPROVE-WITH-FIXES), all fixes applied (30 verbs; engine 34 functions/753 lines + full function list; FallbackLease :86; TransitionVerb move pins TRANSITION_VERBS/VerbSchema/events.ts and forbids the store↔transitions cycle; capability shape pinned to no-op transport methods + buildSeatCfg moves to transport-ssh; Partial<Record> fallback pinned; raw-fetch sites named (AttemptDetailDrawer.tsx:97, FactoryTraceTables.tsx:75) with corrected deletion grep excluding `refetch(`; new fleet delegation failure test specified; 3.4 depends on shared-contracts D6). Three plans registered PROPOSED in docs/plans/INDEX.md. Nothing implemented, nothing launched.

## Next executable action

Owner approval to launch; then shared-contracts plan lands first. Until then: none.