# Proof audit, pass 1 — provider account badges on subagent avatars

PR [#25031](https://git.cafe/pingdotgg/t3code/pull/25031), branch `fix/issue-24896`. Reviewed head [fd6f84adeb](https://github.com/pingdotgg/t3code/commit/fd6f84adebd5592fff1df47f903ad260c389f2bd), against the requested base [32ecd71726](https://github.com/pingdotgg/t3code/commit/32ecd71726fee16f335484c1f95cbce126d461f6). Read-only, code-derived capture plan; no new captures exist and no server, browser, device, or provider was started by this audit. Seeding feasibility below is traced from code, not a claim that a driver has already run. The PR metadata agrees with the requested head/base. The local `main` ref has a different merge-base, so the explicit supplied base was used throughout.

## Findings first

1. **Proof blocker: every affected row below is missing at this head.** Existing description evidence is from older revisions, and its own limits admit schema-invalid injected projections, injected project settings, blank navigation frames, and a hovered still. It is not accepted as fresh persistence, settings, interaction, or timing proof. This pass designs the replacement matrix; it makes no merge-readiness claim about the implementation.
2. **Use actual settings and actual app-owned children for the main path.** `server.updateSettings` accepts provider-instance mutations and project overrides. `orchestration.dispatchCommand` accepts `delegated_task.request` and creates the child thread, parent subagent record, node, lifecycle turn item, and child message/run through orchestration. A free local ACP replay instance can keep the parent waiting on a real approval, then create two, three, or five children on that same active run/provider turn. This avoids injecting projections for the primary badge, stack, settings, and navigation proof.
3. **Native workflow and exact status-edge fixtures are a distinct provenance class.** The stock dev replay provider has only showcase, plan/reads, approval, question, and multi-turn scenarios. It does not expose a native workflow or native subagent scenario. Claude's adapter tests contain concrete workflow SDK frame builders and native replay fixtures exist, but these are test harnesses, not browser console commands or public “set workflow” RPCs. Use those through an explicitly labelled harness unless a live Claude workflow is actually driven. Do not relabel a schema-valid injected projection as an RPC-created workflow.
4. **Do not overclaim mobile scope.** The changed mobile avatar is the grouped header only. Expanded/standalone mobile rows use `SubagentRow`, whose metadata icon remains a plain `ProviderIcon`; the group header has no status dot. The top-left status-dot change applies to web lifecycle/notification/workflow member avatars. Mobile handoff is a refactor that must preserve both committed rows and the pending footer, including endpoint alerts. Both Android and iOS need native proof for stacking; Android does not establish iOS z-order or inspector navigation.
5. **Several identity cases need deliberate coverage.** Badge eligibility uses the child's environment, enabled siblings (including project-enabled snapshots), historical disabled accounts, normalized accent colours, and ACP registry agent identity. Provider readiness/usage exhaustion does not enter the badge rule. Default instance IDs repeat across environments, so an apparently correct local capture is insufficient for remote scoping.

## Capture notation and acceptance

- `W` = Chromium web, 1440×900 CSS px; `N` = Chromium web, 390×844 CSS px. Use the same DPR, fonts, zoom, fixture state and pointer position before/after; DPR 2 is a reasonable fixed choice.
- `D` = Electron desktop, 1440×900 content area (record actual content dimensions). Desktop renders the same web tree with no changed IPC/platform branch; one integrated smoke repeats W01 rather than duplicating the entire web matrix.
- `A` = native Android phone, approximately 390×844 logical viewport; record device and actual logical/physical dimensions. `I` = native iOS phone at the same approximate logical size. `T` = iOS tablet/landscape with `fileInspector.supported`, at least 1024×768; record actual window width and pane width. This covers the inspector-specific interaction, not a separate badge algorithm.
- `L/Dk` = light and dark themes. `W,N × L/Dk` means all four cells. `A,I × L/Dk` means both platforms in both themes. A mobile-web viewport is not native mobile evidence. This VM is Linux; use a device session/remote simulator for native captures. No device availability was checked in this pass. If one cannot be obtained, retain that platform as missing; a harness does not become native proof.
- **Every `recording` row requires continuous before/after clips**, showing the described interaction or time transition and stable endpoints. Endpoint stills alone do not satisfy it. Stills may accompany the clip for pixel comparison. Rows marked `still` are stable, pre-seeded scenes with no interaction claim. A shared contact sheet or clip may satisfy several rows if the IDs, state and readable avatars remain identifiable; the matrix is not a demand for one file per row.
- All affected rows need a before/after pair at the requested base and reviewed head. Earlier unrelated heads may be supplemental only. Match state by identifiers/meaning, not random elapsed durations. Freeze clocks only for stable stills; active-clock recordings must show the clock advancing and stopping. No blank/white-frame navigation edits, hidden route swaps, or clips from different flows. Move the pointer to an empty gutter before static captures; deliberately show hover/focus only in their recording.
- Record each fixture's seed provenance, RPC request/receipt identifiers (redacted), schema-decode result, `getThreadProjection` read-back, visible route, providers/settings read-back, and capture cell. Keep tokens, startup pairing links, credentials and personal data out of evidence. Do not use `createdBy: "assistant"`; valid actors are `user`, `agent`, `system` (message `role: "assistant"` is a separate field).
- Labels: **REAL-RPC** = normal fresh dev server, real settings RPC and orchestration-created state; synthetic replay content is disclosed. **NATIVE-PROVIDER** = actual provider emitted native events. **HARNESS** = scripted adapter/events/projections or mounted component state; label the exact boundary. Schema validation alone does not upgrade HARNESS to REAL-RPC.

## Complete changed-component caller and branch inventory

### Web

Sources: [TimelineV2EventRow.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/components/chat/TimelineV2EventRow.tsx), [V2LifecycleRow.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/components/chat/V2LifecycleRow.tsx), [WorkflowOpeningBlock.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/components/chat/WorkflowOpeningBlock.tsx), [ProviderInstanceIcon.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/components/chat/ProviderInstanceIcon.tsx).

| Changed component/function | Every caller/render path | Layout inputs, branches and interactions | Matrix coverage |
|---|---|---|---|
| Private `SubagentAvatar` | Only `EnvironmentSubagentAvatar` | Optional driver: provider icon versus Bot fallback; optional displayName/icon URL; new `accentColor`, `showBadge=false`; new compact provider icon (14px logo, compact initials badge); outer 24px circle; optional `className` receives stack z-index. Status absent means no dot; present means 8px dot. Badge present moves dot top-left; absent leaves bottom-right. Pending/running/waiting blue; completed green; failed red; idle muted/50; cancelled/interrupted muted/60. Theme affects background/ring, text, logo and badge border. No avatar-specific click, loading, spinner, quota, error-message, breakpoint or animation branch. | W01–W10, A01–A08, R01–R03 |
| `EnvironmentSubagentAvatar` and new `subagentProviderBadge` | Exactly three direct call sites: (1) group header in `V2SubagentGroup`; (2) `SubagentTimelineLink`; (3) `WorkflowMemberRow` | Scope = `remote.environmentId ?? environmentId`; primitive provider driver, name and icon selectors; separate settings atom; missing provider/settings/empty provider map; badge entry versus none; new label/accent selectors. Display name = badge label then provider name. Local missing snapshot falls back to item driver; remote missing snapshot suppresses the local `remote` driver and uses Bot. Branding uses settings for ACP identity; enabled flags use actual server snapshots, preserving project-enabled siblings. Settings or provider pushes must update badges without navigation; status-only pushes must not visually reset avatars. | A01–A08, R01–R03 |
| `V2SubagentGroup` | `MessagesTimeline` → `V2EventTimelineRow`, only when subagent and `(row.subagents?.length ?? 1)>1` | Members must be subagent items; live projection overrides item status/times. Adjacent events group only for same `runId` AND `providerTurnId` in `MessagesTimeline.logic`. Two circles; three circles; >3 uses first three plus `+N`. New stacking z classes 3,2,1. `agents.length===1` status-dot expression is unreachable on a valid grouped event; real singleton routes to lifecycle instead. Expanded or active = full opacity; inactive collapsed = .55 opacity; hover restores opacity. Active summary blue wins over failed; inactive failed red; settled neutral. Label/count, summary truncation, timer shrink, chevron rotation; collapsed versus bordered expanded lifecycle rows; `continuesWorkLog` context. Click/keyboard toggles, work-group persistence/scroll anchoring, hover. | W01–W04, A01, D01 |
| `V2LifecycleRow` → `SubagentTimelineLink` | Direct singleton from `V2EventTimelineRow`; members of expanded `V2SubagentGroup`; notification link below | Item/provider/subagent IDs, optional title (fallback Subagent and title formatting), origin, childThreadId or remoteChild, status, progress/result/times. Live record overrides status/detail/time. Settled uses result before progress; active progress before result. Empty/generic child-end detail hides; plain path without spaces uses MiddleTruncate; other text truncates. Failed detail/label red; detail plus noncompleted status adds trailing label. Child thread = button/chevron; linked remote with no local child = remote route button; neither = noninteractive div. Elapsed absent/live/settled. Hover tooltip after delay and focus, open child and return; remote label consumes narrow width. Other lifecycle kinds (interrupt, handoff, fork, thread-created, null) never call the changed avatar. | W01, W03, W05, W06, R01,R02,Z01 |
| `SubagentNotificationLink` → same lifecycle avatar | `TimelineWorkEntryRow.SimpleWorkEntryRow` when notification has a child thread source | No matching subagent returns unchanged WorkEntry fallback. Matching child uses parent record's instance/origin/driver/title and can recover `remoteChild` from live agent. Completed/failed/cancelled outcomes provide event dot and Finished/Failed/Stopped label + event timestamp; updated/unknown provide null status → no dot, Updated/Finished label. For terminal outcomes, a child resumed since notification time instead shows live status/elapsed. Result/detail and child navigation/tooltip branches inherited. | W07,W08 |
| Unchanged `WorkflowMemberRow` invokes changed avatar | `MessagesTimeline` → `TimelineUserMessageRow.UserMessageRow` replaces workflow-opening user message → `WorkflowOpeningBlock` → phase members and unphased members | Uses coordinator opening provider instance/driver for every member, not a member's model or task ID. `opening.providerInstanceId===null` yields no member rows. Empty phases filtered; phased section has settled count; unphased list has no phase heading. Each member's status sets dot; queued maps pending, running, completed, failed. StartedAt missing hides time; otherwise live/fixed elapsed. Terminal detail chooses error/result/progress, active chooses progress; missing/long title/detail; childThreadId null = div, nonnull = button + chevron. Tooltip and child navigation. Opening name/description/group-loaded fallbacks, empty members, short versus folded long script and Show full script/Show less/find reveal are surrounding branches; no separate avatar code in script. | W09,W10,Z01 |

### Mobile and shared identity rule

Sources: [thread-subagent-group.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/thread-subagent-group.tsx), [thread-work-log.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/thread-work-log.tsx), [ThreadFeed.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/ThreadFeed.tsx), [thread-provider-instance.ts](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/thread-provider-instance.ts), [thread-handoff-row.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/thread-handoff-row.tsx), [ProviderIcon.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/components/ProviderIcon.tsx), [SubagentRow.tsx](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/SubagentRow.tsx), [shared badge rule](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/client-runtime/src/state/providerInstanceDisplay.ts).

| Changed component/function | Every caller/render path | Layout inputs, branches and interactions | Matrix coverage |
|---|---|---|---|
| Private mobile `SubagentAvatar` | Only first-three header avatars inside `ThreadSubagentGroup` | Item instance/driver/remoteChild; providers array and surfaceColor. Matching provider resolves real driver. Missing local provider falls back to item driver; missing remote provider → 13px sparkles. Known driver+eligible provider → 15px `ProviderInstanceIcon`, logo opacity .6, 12px badge protruding bottom-right; otherwise plain 15px `ProviderIcon` full opacity. Outer 28px bordered card circle. No status dot in either branch. ProviderInstanceIcon uses normalized accent and contrasting text, neutral bg-card otherwise, border supplied `edgeFadeColor` (screen color). Theme/font/native zIndex affect result. | M01–M04,A01–A08,R01–R03 |
| `ThreadSubagentGroup` | `ThreadFeed` activity-group fallback → `ThreadWorkLog`, when first activity is subagent; `ThreadWorkLog` returns null before this for empty activities | All activities flatMap subagent members; first member used for parent detail subscription (zero members is not a supported direct input). Same run/provider-turn grouping boundary in `threadActivity.groupAdjacentActivities`. Live status/times/result/progress/model override item. `agents.length>1` shows header; one shows rows only. Two/three/>3 first-three + `+N`; new zIndex 3-index and negative margins. Active/failed/neutral summary colour; one-line label/summary; elapsed missing, ticking active, or fixed settled. Expand/collapse controlled by expandedRows/anchorKey; row press disabled when no target. Local/connected remote opens phone stack route or supported iOS inspector; disconnected remote/provider-managed row is noninteractive. Expanded rows use unchanged `SubagentRow`, no new header-style badge. Props iconSubtleColor and edgeFadeColor are passed from feed screenColor. | M01–M06,R01,R02,Z01 |
| New `resolveBadgeProviders` | Exactly `ThreadSubagentGroup.providersOf` and `ThreadHandoffDivider.endpointProps` | Null/undefined config → []; otherwise maps every provider, keeps driver and enabled/status fields, adds driverKind; trims/validates accent to six-digit hex; reads matching settings instance config. Null/nonobject/no config → no agent identity; source local ignores agentId even if stray; registry/other source trims nonempty string agentId or returns undefined. No provider filtering. Existing thread-list resolver exports in same file are unchanged and do not call this helper. | A01–A08,R01–R03,H01–H04 |
| `ThreadHandoffRow` | `ThreadFeed` activity-group where `isContextHandoffActivityGroup` | Nonhandoff or absent endpoints returns null; actual handoff resolves endpoints from item + live runs using atom/memo. Failed status red icon; normal supplied colour. Passes Context handoff label and failed flag to divider. | H01,H03,H04,Z01 |
| `ThreadHandoffDivider` | (1) `ThreadHandoffRow` committed event; (2) `ThreadFeed.ListFooterComponent` when pendingHandoff, label Context handoff pending | New helper replaces previous inline provider mapping exactly. From endpoints: zero=no arrow, one=one source+arrow, many=commas+arrow; to always renders. Wrapping flex row, long labels max width; pending versus committed versus failed. HandoffEndpoint provider exists or absent, model catalog hit uses short/name; unknown model uses raw model; no model uses provider displayName or raw ID. Badge eligible icon size14 versus unbadged12. Endpoint press opens native account alert; neutral/accent themes + screen-colour badge border. Empty timeline/no provider change/compatible continuation group suppresses pending footer upstream. | H01–H04 |
| `shouldShowInstanceBadge` (unchanged, newly used on paths) | Web uses derived environment entries + settings branding; mobile uses new helper providers; mobile handoff now shares helper | Accent present always badge (normalized before call). Otherwise >1 sibling of same driver; if current entry enabled, disabled candidates excluded; if current disabled, all candidates counted for historical distinction. ACP candidates must have equal registry agent ID (local undefined counts with local undefined). Different drivers/environments never pool. Readiness/error/availability/exhaustion/model count do not participate. Display name explicit non-provider label; otherwise custom ID humanization, then default provider name. Initials = first two Unicode characters for one word or first characters of first two punctuation-separated words; label text not rendered in header. No combinatorial model-catalog/usage-card matrix needed. | A01–A08,R01–R03 |

No new public contract, backend, adapter, keyboard command, settings entry point or scheduled-task implementation is changed. Settings are a necessary input to the visual paths, not another changed screen. Web+Electron and native mobile are distinct clients. Connection transport (direct/relay/tunnel) does not change markup; remote environment identity and client disconnection do, and are covered explicitly. Native icons resolve built-in, packaged SVG, ACP image/fallback, or generic fallback shapes; test these morphology classes, not every model offered by every provider.

## Concrete seeding recipes

### S0 — fresh isolated real server and schema/read-back discipline

The capturer, not this audit, starts `T3CODE_DEV_SEED=0 vp run dev` from the lead's assigned checkout, after checking setup markers and choosing a genuinely fresh isolated home (the lead may use an explicit new `--home-dir` below its own scratch). Do not erase the lead's `.t3` or touch live userdata. Read actual ports from dev-runner, pair normally, and keep credentials private. Create a disposable project with `projects.mutate` input `{type:"project.create", commandId, projectId, title:"Avatar proof", workspaceRoot:<existing disposable workspace>}` or `node apps/server/src/bin.ts project add --base-dir <isolated-home> <workspace>`. The project command goes to `projects.mutate`, not orchestration.dispatchCommand.

Use the actual typed RPC transport (`WsRpcGroup`, client-runtime RPC protocol/session) or the UI's existing commands; do not invent a JSON REST `/rpc` endpoint or an `orchestration.startTurn` method. Start a thread with `orchestration.launchThread` (workspaceStrategy `{type:"root"}`, projectId, title, modelSelection, runtimeMode `approval-required`, interactionMode `default`, initialMessage `{text:"go",attachments:[]}`, unique commandId/threadId/messageId). This is what the shared client's bootstrap `startThreadTurn` calls. Public `thread.create` followed by `message.dispatch` through `orchestration.dispatchCommand` is another supported route.

Read `server.getConfig` and subscribe to server config changes for real provider/settings snapshots; read `orchestration.getThreadProjection` and subscribeThread for persisted state/events. Check the captured projection with `Schema.decodeUnknownSync(OrchestrationV2ThreadProjectionJson)` on JSON, or encode/decode the typed projection with its matching typed schema. Do not replace real client atoms/config subscriptions. Wait for the actual milestone event/receipt, never seed “after N seconds”. Active-clock capture naturally observes wall-clock changes.

Useful sources: [RPC schemas](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/contracts/src/rpc.ts), [commands and launch schema](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/contracts/src/orchestrationV2.ts), [client start command](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/client-runtime/src/operations/commands.ts#L653).

### S1 — real provider accounts, free replay content

Through `/settings/providers?environmentId=<E>` or authenticated `server.updateSettings`, create two/three instances. Example payload, with real absolute paths substituted (the command is Node's actual executable path):

```json
{
  "patch": {},
  "providerInstanceMutation": {
    "operation": "create",
    "instanceId": "proof_c1",
    "instance": {
      "driver": "acpRegistry",
      "displayName": "C1",
      "enabled": true,
      "config": {
        "source": "local",
        "commandPath": "<absolute-node-executable>",
        "commandArgs": ["<checkout>/apps/server/scripts/dev-replay-agent.ts"]
      }
    }
  }
}
```

Repeat with `proof_vy`, displayName `VY`, accentColor `#EAB308`, and `proof_rt`, displayName `Research Team`, accentColor `#334155` as needed. Neutral C1 plus light VY and dark RT exercises neutral, black-text and white-text badges. Disable all unintended same-identity replay siblings, including auto-seeded `devReplay`, for single-account controls; for pooled fixtures either disable it or explicitly count it. Do not mistake number of child tasks for number of configured accounts. Use `upsert` retaining the entire config when editing; removal is `operation:"remove"`. This uses actual settings and the actual ACP adapter; content is synthetic. It proves the changed component with an ACP logo, not a native Claude/Codex logo.

The driver includes even warning/error/disabled snapshots; only enabled identity counts enter the rule. A historical instance can be renamed, disabled, removed or changed to registry identity after its child completed, without needing to launch a disabled/unprepared provider. Require `server.getConfig` read-back after each save/reconciliation before capture. Brand-specific Claude/Codex rows use S4 instead.

Sources: [instance mutations](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/contracts/src/providerInstance.ts), [ACP settings](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/provider-acp-registry/src/settings.ts), [dev replay scenarios](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/scripts/dev-replay-agent.ts), [automatic replay instance](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/provider/ProviderInstanceRegistryHydration.ts#L83).

### S2 — real app-owned grouped and singleton lifecycle rows

1. With S1 accounts available, launch parent on `proof_c1`, model `approval`, mode `approval-required`; await its persisted pending approval/runtime request. Keep that approval unanswered so the parent is a blocking run. Read its active `run.id` and `rootNodeId` from `getThreadProjection`.
2. On that parent, call `orchestration.dispatchCommand` consecutively with the following input, fresh commandId per child and desired title/model/instance. Existing `delegate_task` MCP performs the same command, but requires an active, matching provider MCP session and an orchestration capability call; calling it from this review thread would target the wrong server. A scratch authenticated RPC driver is the appropriate seed mechanism.

```json
{
  "type": "delegated_task.request",
  "commandId": "<unique>",
  "createdBy": "user",
  "creationSource": "web",
  "parentThreadId": "<parent>",
  "parentRunId": "<active-run>",
  "parentNodeId": "<root-node>",
  "task": "Read the fixture and report",
  "title": "Fixture child C1",
  "modelSelection": {"instanceId": "proof_c1", "model": "approval"},
  "runtimeMode": "approval-required",
  "interactionMode": "default",
  "completionWake": "settled_only"
}
```

The public WebSocket dispatch handler normalizes creation provenance to `createdBy:"user"`; the example uses that honest provenance. An actual provider MCP `delegate_task` uses `createdBy:"agent", creationSource:"mcp"`. Both actors are schema valid; read back what the server stored, and never assume a client-supplied actor survived normalization. See the [dispatch handler](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/ws.ts#L1874).

3. Two calls give group-of-two; three give three stack positions; five give `+2`. Keep parent run/provider turn identical and avoid intervening parent timeline events. Hold each child on its own actual replay approval until all child lifecycle items exist, so completion notifications cannot split the adjacent group during creation. Verify the resulting projected lifecycle items really group in the app. The orchestrator immediately sets app-owned tasks running, creates child threads through `makeSubagentChildThread`, and starts child runs via effects. Do not assume this command creates native pending/idle states.
4. For a stable settled group, answer child approvals with `runtime-request.respond` using each request's actual decision options (or the UI) and await each persisted terminal event. Use `showcase` child model for a natural streaming→completed example when holding is unnecessary. For singleton rows, use a separate parent with only one child or place children in distinct parent runs/provider turns. For failure, a controlled failing provider process can produce a real failed run; if using a fake process, label it protocol HARNESS. For stopping a running app-owned child use `thread.stop` on the child's actual ID (or UI), not an unsupported native `subagent.stop` guess. Inspect persisted outcome rather than guessing whether it is cancelled or interrupted.
5. Open web route `/$environmentId/$threadId` using the app's `buildThreadRouteParams` (scoped IDs may need route encoding), or select the parent in the native Thread screen. Expand work-log folds if needed. Captures must show real server-loaded rows. At teardown stop only fixture threads/processes created by the driver.

Sources: [delegated command implementation](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/orchestration-v2/Orchestrator.ts#L7285), [MCP command path](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/mcp/OrchestratorMcpService.ts#L2179), [server child/artifact helpers](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/provider-core/src/server/subagentProjection.ts), [web grouping condition](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/components/chat/MessagesTimeline.logic.ts#L1967), [mobile grouping](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/lib/threadActivity.ts#L944).

### S3 — real settings edge cases and live changes

Use S1 historical child rows and real `server.updateSettings` saves (or the actual providers/settings UI); record the save plus config reconciliation plus the unchanged thread updating.

- Single account: only `proof_c1` enabled, no accent. Accent-only: only that account, add `#334155`, then `#EAB308`, then remove accent. Invalid/whitespace hex is normalized away; invalid strings can be saved through RPC even when UI constrains input. Keep schema-valid nonempty settings strings; missing fields cover empty name/accent defaults.
- Historical disabled distinction: create children while both enabled; disable VY with no accent on either. Enabled C1 should lose its badge; disabled historical VY counts both and retains its badge. Disable both: both historical avatars remain distinguished. Re-enable both to restore. No disabled-provider launch is required.
- Project sibling: set VY globally disabled (no accent) and save `patch.projectSettingsOverrides` containing `{ "<real-project-id>": { "providerInstances": { "proof_vy": { "enabled": true } } } }`. Preserve unrelated override keys. The real registry hydration merges project-enabled accounts into its enabled snapshot. Read back global settings `enabled:false`, project override `enabled:true`, AND the real `providers` snapshot with VY enabled. C1 now shows a badge even if its thread is in another project; this is environment-wide identity, not only the active project's picker. Then remove/disable the override and observe reversal. No injected config snapshot is acceptable for this row.
- ACP identity: after local replay children settle, save registry settings for historical instances using valid catalog agent IDs. Two instances with the SAME agentId and no accent badge; two DIFFERENT agentIds and no accent do not. Local source ignores even a stale/stray registry agentId; two local instances still match. Catalog preparation is unnecessary for reading historical avatars; verify providers remain in real getConfig even if unprepared/warning. A missing snapshot must be labelled as such, not treated as success of the identity fixture.
- Names: use a long explicit name with punctuation and Unicode; default-driver displayName plus custom instance ID tests humanized-ID fallback; omitted displayName/default ID tests provider-name fallback. A raw whitespace-only name is not schema valid. Confirm expected initials from the shared helper, not a hard-coded assumption.
- Missing local provider: remove its configured custom instance only after creating its historical child. Item driver remains, icon should remain driver-based but badge disappears. Unknown driver icon/fallback is S4 harness unless an actual installed package exposes it. New provider readiness status pushes do not create an avatar loading/error UI; use snapshots' error/warning history to demonstrate that badges persist, rather than inventing quota-card states.

Sources: [settings patch](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/contracts/src/settings.ts#L1519), [real project-enable hydration](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/provider/ProviderInstanceRegistryHydration.ts#L43), [web environment derivation](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/providerInstances.ts#L84), [existing project-enabled test](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/web/src/providerInstances.test.ts#L229).

### S4 — native subagent, workflow, notification-edge and icon harnesses

**No public RPC sets `workflow`, arbitrary `subagent.updated`, native task status or projection payload.** Server-internal provider events are not `dispatchCommand` commands. `delegated_task.remote.*` is also internal, not a browser seed API.

For a NATIVE-PROVIDER route, configure two actual Claude instances through S1's mutation with driver `claudeAgent` and a valid provider config, and run a cheapest-supported native task/workflow through that provider. Claude/Codex executables are installed on this Linux VM, but this audit did not test account authorization, native workflow availability or run a paid turn; do not promise those are ready. Workflow prompt requests a real native Workflow with phase and unphased agents; the captured provider must emit `local_workflow`/`workflow_progress`, not ordinary delegation that happens to be titled Workflow.

Concrete repository harness paths, which must remain labelled HARNESS:

- [Claude replay integration](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/orchestration-v2/testkit/ClaudeReplayFixtures.integration.test.ts) reads `fixtures/subagent/claude_transcript.ndjson`, materializes `subagentInput()` with `materializeFixtureInput`, runs `runOrchestratorV2Scenario` under `ProviderReplayHarness.layerProviderReplay(..., ClaudeOrchestratorReplayHarness)`. It creates real server child artifacts, and its [output assertions](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/orchestration-v2/testkit/fixtures/subagent/claude_output.ts) assert `createdBy:"agent"`, native lineage, child user/assistant messages and lifecycle items. Other existing fixture directories cover `claude_background_subagent_lifecycle`, `claude_subagent_resume_after_restart`, `subagent_v2`, and `subagent_continue`.
- [ClaudeAdapterV2 workflow tests](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts#L13090) define **test-local, non-exported** `makeWorkflowHarnessWithOptions`/`makeWorkflowHarness`, `workflowToolUse`, `workflowTaskStarted`, `workflowLaunchAck`, `workflowSnapshot`, `workflowNotification`, `launchWorkflow`. They emit a Workflow tool use, system task_started with task_type `local_workflow`, launch acknowledgement with transcriptDir/runId, then task_progress with workflow_phase and workflow_agent entries. `queued/start/done/error` wire states map to pending/running/completed/failed. The existing test demonstrates `workflowScript:true` on the coordinator's first user message and plain subagent briefs marked false. Copy/adapt the minimal builder data into a scratch driver if needed; do not import the test file or claim these are callable app APIs.
- To create a persisted harness, compose a scratch server/test runtime around `makeClaudeAdapterV2` and those fake SDK frames, consuming adapter events with `ProviderEventIngestorV2.ingestNormalized` and a disposable disk database (or use the exported replay harness with a supplied disk databaseLayer). The stock replay harness defaults to an in-memory DB and test settings; it neither starts an HTTP server nor configures the real Settings screen. A runtime/export/transport bridge is work for the capturer, not an existing ready-made command. Read the resulting schema-valid projection into an explicitly labelled visual harness if not running that full runtime. Do not open the lead's live dev DB with a second writer.
- For a minimal render-only HARNESS, construct native children with exported `makeSubagentChildThread` and `makeSubagentConversationArtifacts`; the latter writes valid agent/provider creation fields and optional workflowScript. Construct the matching parent subagent, node and lifecycle turn item with coherent IDs. Workflow opening requires a provider-native child (`creationSource:"provider"`, lineage relationship subagent, parentThreadId), first user script marked workflowScript true, and a parent coordinator subagent whose `workflow` has phases + agents. Setting `workflow` on an app-owned thread does not reach `WorkflowOpeningBlock`. Use actual instance configs from S1/S3 where possible, and disclose any harness-specific provider branding.
- Keep the coordinator running while showing mixed queued/running/terminal members: runtime derivation maps an unfinished member to its coordinator's terminal status once the coordinator ends. For an all-settled scene, settle the members and coordinator consistently. Workflow members support childThreadId present/absent and omitted startedAt; omit `phaseIndex` for unphased data (do not put null in the wire schema), use proper numeric epoch milliseconds for workflow-agent timestamps, and proper ISO/DateTime encoding for subagent timestamps. `opening.group:null`/providerInstanceId null is a temporary parent-not-loaded state with no avatar, not a blank screenshot acceptable as workflow proof.
- Exact idle/pending/interrupted status palette, updated/unknown notifications, missing live parent record, missing remote config, and generic unknown-driver icons may need the same schema-valid labelled visual harness. Real completion notifications can instead be produced by S2 with completionWake always (parent held active) and persisted completion delivery. Real child reactivation produces a resumed notification path if a later run actually starts on that child. Verify the stored notification source resolves `notificationChildThreadId`; simply posting text “Finished” is not the notification path.

### S5 — two real linked environments, not renamed local fixtures

For R01/R03 use a second **fresh server on this same VM**, its own home/port/environment ID and the same S1 instance IDs with deliberately different names/colours. Configure/link it through normal `peerLinks.link` / environment connection flow; connect both clients to both environments. The seed agent's provider-owned MCP session can call `orchestrator_capabilities` then `delegate_task` with target.environmentId/projectId/providerInstanceId/model through that environment's actual MCP endpoint. Alternatively a scratch in-process driver can use the exported remote delegation service, explicitly labelled server harness. The internal `delegated_task.remote.request/complete` commands alone are not public RPCs and do not establish a real peer link.

Require parent task `childThreadId:null`, a real `remoteChild:{environmentId,threadId,label,...}`, and target environment's real server config. Give local and target environments the same instance ID but different badge colours/names; put an extra enabled sibling in only one environment. A remote task driver on the parent can just be a remote label, so a local provider fallback is wrong. Record click into the actual target route and back. Then test one account per environment: two environments do not make a pool. For R02 disconnect the target client/environment so there is **actually no target config** in the client; verify it is absent rather than cached. If caching prevents reaching that branch reliably, use labelled HARNESS with missing target config and retain real reconnect/navigation as separate evidence. Do not touch the user's existing linked environments.

Sources: [remote delegation service](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/mcp/OrchestratorMcpService.ts#L2179), [remote records test helper](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/server/src/orchestration-v2/RemoteDelegatedTask.test.ts), [mobile navigation target](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/threadAgentsPresentation.ts), [iOS inspector branch](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/apps/mobile/src/features/threads/thread-inspector-navigation.ts).

### S6 — real mobile handoff and labelled endpoint edges

Run a normal S1 replay turn to completion on C1. Change composer selection to VY and inspect pending footer before sending; the two local ACP instances have distinct instance-based continuation keys, so this requests a handoff even though they run the same replay script. Send the next turn, await actual handoff item and completed target run, capture committed divider. The shared client uses `provider.switch`/message dispatch as appropriate; do not fabricate a pendingHandoff prop for this REAL-RPC row. Record tap on each endpoint and its native alert, then dismiss and return. A failed context preparation or controlled provider failure can seed failed handoff only if a failed handoff item really persists; otherwise use the labelled harness for that branch.

Zero from endpoints, multiple distinct sources, obsolete model IDs, no model, unknown/removed provider, null config are legitimate render inputs but not all are readily emitted by a two-turn replay. Use a typed `ThreadHandoffDivider`/`ThreadHandoffRow` harness for deterministic endpoint combinations, with actual S1/S3 config where available. `resolveHandoffEndpoints` uses explicit fromModelSelections first; otherwise fromProviderInstanceIds with the latest prior run's model; target explicit toModel first, then matching handoff run. Test both data shapes, not just a visually identical populated one. Source arrays can be empty in schema; one arrow appears only if nonempty. No pending footer for an empty timeline or no real continuation change (guard Z01).

Sources: [handoff derivation](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/client-runtime/src/handoff.ts), [instance continuation identity](https://github.com/pingdotgg/t3code/blob/fd6f84adebd5592fff1df47f903ad260c389f2bd/packages/provider-acp-registry/src/server/driver.ts#L484).

## Fixture matrix — every row's pass-1 status

`Affected` includes regression controls that execute changed markup/helper paths even if no badge should appear. Only M05/Z01 have no changed avatar output. Cell selections deliberately avoid a Cartesian product: common badge/theme/width effects are paired in the principal rows, identity-equivalence rows use representative cells, and native platform stacking is repeated on both operating systems.

| ID | Named fixture and exact distinguishing data/state | Affected? | Minimum capture cells | Evidence type / required action | Seed path and provenance | Pass-1 status |
|---|---|---|---|---|---|---|
| W01 | Pooled two-account settled group; C1 neutral + VY yellow; two completed children, same parent run/provider turn; collapsed .55 opacity and expanded full-opacity rows with green top-left dots | Yes | W,N × L/Dk | **recording**: expand/collapse by pointer and keyboard; stable pointer-away endpoints | S0–S2 REAL-RPC; preserve real lifecycle items, not injected group props | **MISSING** |
| W02 | Exactly three settled children, C1/VY/RT (neutral/light/dark accents), all three badge positions visible; no overflow count | Yes | W × L/Dk; N × Dk | still, fully collapsed, no hover | S2 with three held children then settle; REAL-RPC | **MISSING** |
| W03 | Five children / +2 overflow; all settled with at least one failed; long title, long prose and a no-space path detail among expanded rows; inactive-failed header red | Yes | W,N × L/Dk | **recording**: disclose, scroll all five, collapse; no blank navigation frames | S2 real count/long titles; controlled failure through provider protocol HARNESS if real failed item cannot be made; label that subcase | **MISSING** |
| W04 | Active group with working+failed+done summary, valid start times; working summary blue wins; active→all settled, elapsed advances then stops; missing-start/end control | Yes | W × L; N × Dk | **recording**: at least two visible clock increments, terminal event, frozen settled result; hover changes opacity only when inactive | S2 real replay waiting/streaming→complete; unusual missing timestamp subcase S4 HARNESS | **MISSING** |
| W05 | Isolated lifecycle status palette: pending/running/waiting blue; completed green; failed red; idle muted/50; cancelled/interrupted muted/60. Show badged and no-badge equivalents; empty/generic detail, long prose/path and absent elapsed | Yes | W × L/Dk; N × Dk for long text | **recording** for active/status transitions; settled palette stills may share sheet | S2 real singleton running/waiting/completed/stop read-back; S4 labelled HARNESS for exact pending/idle/interrupted or missing-time states not emitted by replay | **MISSING** |
| W06 | Standalone and expanded lifecycle actionable child versus provider-managed nonactionable row; keyboard focus ring and delayed tooltip; local child route opens/returns | Yes | W × L; N × Dk | **recording**: focus, hover tooltip, open child, return, leave pointer away | S2 REAL-RPC for local child; childThreadId:null/no remote S4 native fixture/HARNESS | **MISSING** |
| W07 | Notification renderer with matching child: completed/failed/cancelled event dots + fixed timestamp, updated/unknown outcomes with no dot; detail/label trailing differences | Yes | W × L/Dk | still for fixed notification outcomes; **recording** if invoking notification delivery/navigation as proof | S2 REAL-RPC completion delivery when actually emitted; S4 HARNESS for exact updated/unknown/outcome combinations; disclose split | **MISSING** |
| W08 | Old terminal notification followed by child resume: switches from event timestamp/dot to live status/elapsed; missing matching subagent falls back to ordinary work entry | Yes (fallback control) | W × L; N × Dk | **recording**: persisted old notification → new child run; open/back; fallback is stable subcase | S2 real child message dispatch with completionWake always and actual later run; S4 HARNESS if that source/resume path not reached | **MISSING** |
| W09 | Native workflow coordinator opening with nonempty phases, named phases/settled counts; queued/running/completed/failed members, missing vs present startedAt, long member title/detail; pooled coordinator instance badge | Yes | W × L/Dk; N × Dk | **recording**: member update/timer, tooltip, child open/back, long-script fold/unfold | S4 NATIVE-PROVIDER only if actual Claude workflow emits it; otherwise explicitly labelled adapter/projection HARNESS using workflow builders and valid native lineage | **MISSING** |
| W10 | Unphased workflow members (phaseIndex omitted), nonactionable childThreadId absent and actionable child; short script; empty phases/group-not-loaded control gives no member avatars | Yes (no-avatar control included) | W × L/Dk; N × L | **recording** for actionable member/tooltip; stable unphased/no-child endpoints | S4 labelled HARNESS by default; ordinary delegated children or Muse's generic workflow tool are not this opening path | **MISSING** |
| M01 | Native two-account group C1/VY, collapsed and expanded; header badges only, plain expanded metadata icons; phone child navigation | Yes | A,I × L/Dk | **recording**: tap expand/collapse, open child and return; keep header readable at endpoints | Same S0–S2 REAL-RPC backend, paired native app; no injected native store | **MISSING** |
| M02 | Native exactly-three C1/VY/RT stack; show all bottom-right initials and no clipping at negative margins, both OS zIndex implementations | Yes | A,I × L/Dk | still at settled collapsed header | S2 REAL-RPC | **MISSING** |
| M03 | Native five / +2 overflow; long summaries and failed settled group; expanded long details and scroll | Yes | A,I × L/Dk | **recording**: disclose/scroll/collapse; verify third badge is not covered by +2 | S2 REAL-RPC count; failure boundary labelled if S4 needed | **MISSING** |
| M04 | Active mixed-status native group → completed, clock advances then stops; no elapsed when starts absent / settled completion missing | Yes | A × L; I × Dk | **recording**: real clock ticks + settlement; no frozen active clock | S2 REAL-RPC; missing-time subcase S4 HARNESS only | **MISSING** |
| M05 | Singleton subagent activity has no grouped header; empty work-log has no row; unchanged SubagentRow status/metadata control | No changed avatar output | A × L; I × Dk, can share M01 before second child | still/guard observation; no dedicated clip required | S2 single child; empty via S0 new thread. REAL-RPC | **UNVERIFIED CONTROL** |
| M06 | iOS supported wide inspector branch: group expanded and child opens in inspector rather than phone stack; narrower control opens stack | Yes, interaction around changed header | T × Dk; I × Dk can reuse M01 | **recording**: expand/open/return, keep group mounted and visible; record actual supported layout | S2 REAL-RPC, native iOS tablet/landscape; absent supported device means missing, not Android substitute | **MISSING** |
| A01 | One configured enabled account, no accent: two/three children still overlap but no badge; web status dots stay bottom-right; mobile logo stays full opacity | Yes, regression control | W × L/Dk; N × Dk; A,I × L/Dk | still, includes standalone web + grouped web/mobile; disclosure action may reuse W01/M01 clip | S1/S3 REAL-RPC; disable unintended devReplay/other same-identity siblings and read back | **MISSING** |
| A02 | Single enabled account with accent only: dark #334155 → light #EAB308 → no accent; contrast white→black text; web dot relocates and returns | Yes | W × L/Dk; A,I × L/Dk | **recording**: real setting saves/push updates; stable endpoints also usable as stills | S3 REAL-RPC, no injected colour or config atom | **MISSING** |
| A03 | Badge label resolution: omitted name/default ID; provider-default label/custom slug fallback; long punctuation/Unicode label with predictable max two initials | Yes | W × L; N × Dk; A,I × Dk | still, all initials specimens readable; no full name leaks/wrapping in compact badge | S3 real names/IDs for registered driver; any generic unknown driver S4 HARNESS | **MISSING** |
| A04 | Historical disabled accounts: enabled current excludes disabled sibling; disabled historical current includes both; both disabled retain distinction; re-enable | Yes | W × L; A,I × Dk | **recording**: real disable/re-enable saves and config reconciliation on existing history | S3 REAL-RPC; create children first, no disabled account launch | **MISSING** |
| A05 | Project-enabled sibling: globally disabled VY/no accent, real project override enables VY, snapshot enabled true; C1 badge appears even on other project; removing override removes it | Yes | W × L/Dk; A,I × L (same backend settings) | **recording**: actual save/read-back and thread update/reversal; snapshot injection disallowed | S3 REAL-RPC; show both global settings + project override and real reconciled providers | **MISSING** |
| A06 | ACP identity equivalence: two same registry agent IDs badge; two different IDs no badge; two local instances ignore stray IDs and badge; trimmed registry ID | Yes | W × L; A,I × Dk; handoff reuses H01 | **recording** for changing identity live; fixed specimens allowed as supplemental stills | S3 REAL-RPC on settled historical IDs, registry warning/unprepared allowed but snapshot presence required | **MISSING** |
| A07 | Logo morphology: Claude warm vector, Codex monochrome in both themes, packaged provider SVG, ACP image/fallback, unknown driver initials/fallback; badge and status corners remain readable | Yes | W × L/Dk; A,I × L/Dk for native mobile morphology | still; image load/failure transition, if asserted, is **recording** | S4 NATIVE-PROVIDER when actually configured/run; otherwise labelled schema-valid icon/render HARNESS. Free ACP path alone does not satisfy Claude/Codex morphology | **MISSING** |
| A08 | Settings/config hydration and errors: provider snapshot temporarily absent then arrives; missing settings with providers; invalid accent normalized away; live rename/accent edit; ready→warning/error push leaves badge geometry unchanged | Yes | W × L; A × Dk; I × L | **recording** for hydration/edit/status pushes; missing-settings legacy/config-null edge labelled | S3 real rename, removal and settings saves; S4 HARNESS for deterministic null/error snapshots not reachable in stock client | **MISSING** |
| R01 | Real remote child, same instance IDs local/target but different labels/accents; remote environment has two siblings; local values must not leak; web remote label/narrow layout | Yes | W,N × L/Dk; A,I × Dk | **recording**: actual remote target opens and returns; local and target config evidence | S5 two fresh linked servers REAL-RPC if using actual target MCP session; otherwise explicitly labelled remote server HARNESS | **MISSING** |
| R02 | Remote environment unavailable/no target config; remote driver label must not masquerade as local provider; Bot on web / sparkles on mobile, no badge; reconnect restores target badge/action | Yes | W × L; N × Dk; A,I × Dk | **recording**: real absence/reconnect; noninteractive missing target endpoint visible | S5 real disconnect only if config truly absent; cached config does not reach branch → S4 labelled HARNESS required for absence | **MISSING** |
| R03 | One account in each of two environments, same driver+instance ID; no accent and no cross-environment pooling; target-only accent still badges target | Yes, scoping control | W × L; A,I × L | still for stable pair; accent mutation covered by A02/R01 recording | S5+S3 REAL-RPC, separate environment IDs/configs | **MISSING** |
| H01 | Mobile committed successful handoff, pooled badges on source+target, model-catalog labels and native account alerts; supplementary plural-source comma/wrap case | Yes, helper refactor | A,I × L/Dk | **recording**: tap every endpoint alert/dismiss; plural wrapping stable endpoints | S6 REAL-RPC for two-turn one-source handoff; multiple-source divider S6 labelled HARNESS if not emitted by actual history | **MISSING** |
| H02 | Mobile pending footer → committed successful handoff; same display providers and badge border on screen surface; no duplicate footer after commit | Yes, second caller | A × L; I × Dk | **recording**: change real composer account, pending footer, send, committed divider; no blank frames | S6 REAL-RPC with independent ACP instances/continuation keys; fake pendingHandoff prop is HARNESS only | **MISSING** |
| H03 | Mobile failed handoff red icon/label; explicit fromModelSelections versus legacy IDs+prior-run model; zero/one/multiple sources; raw unknown model truncation/wrap | Yes, helper refactor edge | A,I × L/Dk | **recording** for failed transition or endpoint taps; stable zero/multi-source endpoints also stills | S6 real failed item if reproducible; otherwise labelled typed handoff HARNESS for exact endpoint/history combinations | **MISSING** |
| H04 | Mobile handoff with no catalog model → provider name, removed/unknown provider → raw instance ID; empty config/no badge; single-account/ACP differing IDs control | Yes, helper refactor fallback | A × Dk; I × L | **recording**: alert shows correct name or ID, dismissal; fixed no-config endpoint | S3 real removal after history + S6; no-config/omitted-model shapes S6 labelled HARNESS where not actual | **MISSING** |
| D01 | Desktop integrated smoke of W01 pooled header/expanded lifecycle rows and local child open/back | Yes, shared web client | D × L; dark web equivalent already W01 | **recording**: same state/navigation in Electron, no shell clipping | S0–S2 REAL-RPC with desktop connected to isolated backend; no desktop-specific code branch inferred | **MISSING** |
| Z01 | Negative guards: empty group never directly invoked; non-subagent event uses existing renderer; no parent workflow data gives no member rows; nonhandoff returns null; empty timeline/unchanged compatible provider suppresses pending footer | No changed avatar output | Reuse W10/M05/H02 surrounding scenes; no new visual cells | code + guard observation; blank frames do not count as positive proof | S0/S2 for empty/history guards, S4/S6 labelled harness only for unreachable direct-prop guards | **CODE-TRACED; NO POSITIVE CAPTURE REQUIRED** |

## Minimum execution plan and evidence handoff

1. First create REAL-RPC S0–S3 parents for W01–W06, M01–M04, A01–A06 and real S6 handoff H01/H02. A single backend can serve web, Electron and both native clients. Reuse before/after seed semantics, not a copied invalid projection dump.
2. Capture stable two/three/five stacks and status/identity sheets, then continuous disclosure, navigation, clock, settings and handoff clips. Core W01/W03 include desktop/narrow light/dark; M01–M03 include both native platforms/light/dark. Grouped cardinality and account cardinality are independent.
3. Explicitly label S4 workflows/status/icon/notification-edge and S6 endpoint-edge captures. Retain valid createdBy/lineage/timestamp schema proof. A native workflow coordinator is essential for W09/W10; an app-owned child with a script title is insufficient. Exported test helpers can generate correct data but do not themselves seed a running HTTP server.
4. Run two isolated linked environments for R01/R03; R02 needs actual config absence or a labelled fallback harness. Capture the iOS wide inspector branch separately (M06). If platform/link/provider availability prevents any required cell, report that exact missing cell rather than silently substituting a web or Android scene.
5. Upload full clips/stills plus readable pairs/diffs; name every row/cell/provenance. No blank-frame splicing, hovered baseline labels or frozen active clocks. A pass-2 auditor should verify these against this matrix and actual seed read-backs, not merely count attachments.

No tests or captures were run in this pass. Read-only coverage: all five changed files, all direct callers of changed components/helper, web notification/workflow indirect callers, identity derivation/shared rule, web/mobile grouping, native navigation variants, settings hydration, RPC command schemas/implementations, replay scenario limits and specific native fixture/helper paths. No implementation defect is asserted from this proof-planning pass.

FRICTION: none

VERDICT: INSUFFICIENT W01–W10, M01–M04, M06, A01–A08, R01–R03, H01–H04, D01 (all affected rows lack current-head captures)
