Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a0cc88f
feat(flows): promotion run for 0.5.225 — eight drafts move to testing…
emooreatx Sep 29, 2026
7d4e63d
fix(flows): verify every circle and tab hop landed before the next click
emooreatx Sep 29, 2026
1e0e74a
fix(flows): a flow closes what it opened, whatever its verdict (`clea…
emooreatx Sep 29, 2026
8045b01
fix(client): a state block's tree text carries its body and detail
emooreatx Sep 29, 2026
e2c27a8
fix(two-node): wait for the owner→node binding before opening the room
emooreatx Sep 29, 2026
ecaeffc
fix(session): wait for a wizard step to advance, bounded, instead of …
emooreatx Sep 29, 2026
5d3d2d6
fix(flows): scroll into view on an off-screen refusal, and keep the d…
emooreatx Sep 29, 2026
7d52bc2
fix(flows): an expect after an action settles on the frame, bounded
emooreatx Sep 29, 2026
42ae09f
fix(client): input sinks for the three Provision an accord holder fields
emooreatx Sep 29, 2026
c50c8c2
fix(flows): under the shell, back is the shell's btn_nav_back
emooreatx Sep 29, 2026
4ced0fb
fix(ci): call build_qa_gallery.py as it is written
emooreatx Sep 29, 2026
5477a0b
docs(csd): what each 0.5.225 flow does on the local Linux desktop leg
emooreatx Sep 29, 2026
ca68dae
fix(gate): print UTF-8 whatever code page the host opened the console…
emooreatx Sep 29, 2026
1dcf0b0
fix(client): a disabled Provision submit is disabled to /click too
emooreatx Sep 29, 2026
564159d
fix(flows): a cleanup can be guarded by `when:`, and an off-screen ro…
emooreatx Sep 29, 2026
0acc2f2
fix(client): a node that answers is first-run until it has an owner
emooreatx Sep 29, 2026
3b4ae6f
fix(flows): a cleanup guard reads the frame after the previous close
emooreatx Sep 29, 2026
ccd5e77
fix(flows): the session fixture waits out an in-progress ownership claim
emooreatx Sep 30, 2026
2d5800f
fix(flows): a disabled control's click is refused the same way everyw…
emooreatx Sep 30, 2026
ac05851
fix(client): a disabled button is disabled to /click, and a click wai…
emooreatx Sep 30, 2026
8b6c498
Merge origin/main (#137) into flows/matrix-0.5.225
emooreatx Sep 30, 2026
94d0b0c
fix(gate): a failed claim names its reason, on the screen and in the …
emooreatx Sep 30, 2026
da7e8d8
fix(gate): carry the node's claim PIN into the Android app's home
emooreatx Sep 30, 2026
2698e60
fix(primitives): a sheet's way out stays on screen on a phone
emooreatx Sep 30, 2026
efdac2a
fix(session): a consent answer that did not land is given again while…
emooreatx Sep 30, 2026
e06978a
docs(csd): seven CSDs are testable — their flows passed on all five legs
emooreatx Sep 30, 2026
9a97fc2
Merge remote-tracking branch 'origin/main' into flows/matrix-0.5.225-…
emooreatx Sep 30, 2026
78a73ca
docs(roadmap): seven CSDs testable, 79 CSDs, the drafts are next
emooreatx Sep 30, 2026
80bbb1f
docs(roadmap): restore the sections the last edit cut, keep the promo…
emooreatx Sep 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/five-platform-live-qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ jobs:
path: collected
- name: Build the gallery
run: |
python3 testing/gate/build_qa_gallery.py --shots collected --out gallery.html || \
python3 testing/gate/build_qa_gallery.py collected --out gallery.html --summary "$GITHUB_STEP_SUMMARY" || \
echo "::warning::gallery build failed; the raw artifacts are still attached"
- uses: actions/upload-artifact@v4
with:
Expand Down
6 changes: 3 additions & 3 deletions FSD/CSD/CSD-005-people.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# CSD-005 — People (the Contacts surface, rebuilt on the primitives)

**CSD**: CSD-005 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the Locked Spec, wave 0
**Flow**: `testing/flows/drafts/csd-005-people.yaml` (floor `>=0.5.225`)
**Flow**: `testing/flows/csd-005-people.yaml` (floor `>=0.5.225`)
**Reads with**: CSD-006 (the receipt it opens), CSD-091 (the chat a row opens), CSD-092 (the code card in its header), CSD-104 (the key check a row will offer once CIRISServer#683 lands)

```yaml csd:stage
stage: building
stage: testable
owner: CIRISClient
```

Expand Down Expand Up @@ -219,7 +219,7 @@ again. On a fresh node with no contacts → `card_contacts_add` and no

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-005-people.yaml`, floor `>=0.5.225`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97) The populated list and the receipt step are no longer optional: `fixture: two_node` seeds the contact, and on the Linux desktop leg (2026-09-28) the row, its trust chip, its hamburger and the five-fact receipt all passed. The flow then failed at `the_add_card_opens_with_paste_and_scan`: the desktop add card shows `btn_scan_contact_code_status`, not `btn_scan_contact_code` — a defect in that step, unrelated to the fixture.
**`testable`** since the five-platform run 36775704425 (2026-09-30, `flows/matrix-0.5.225` at efdac2a2, node v0.5.217): the flow (`testing/flows/csd-005-people.yaml`, floor `>=0.5.225`, `fixture: two_node`) passed on all five legs — Linux, macOS and Windows desktop, the Android emulator and the iOS simulator. What follows is how it got there. Linux desktop leg run locally the way `five-platform-live-qa.yml` runs it (2026-09-29, candidate 0.5.225, node v0.5.217, `--flows testing/flows`, the two-node fixture): **11/12 passed, 1 skipped** — the list, the seeded row with its trust chip and hamburger, the five-fact receipt and its close, the empty search and its clearing, the add card, the node-code refusal by name, and the code card from the header; `a_scan_is_offered_where_there_is_a_camera` skipped as designed (desktop has no `btn_scan_contact_code`). The matrix run of the same day (36588619656) failed this flow on every desktop leg for csd-092's open contact-code card, which now closes itself (`cleanup:`), and its fixture waited only for the peer's owner key, not the binding (`reachable_nodes`, CIRISServer#699) — both fixed. Not yet run on the other four legs. On the second matrix run (36600766576) it passed 11/12 on Linux and macOS (the scan step skipped, no camera) and could not start on Windows (the fixture's console crash, fixed in the gate); its last steps left the add card open with a refusal in it, which on macOS's shorter window pushed the list below the fold for csd_006 — the flow's `cleanup:` now clears the refusal and closes the card (`when:` guards the header toggle).

**Platforms.** All five. The Contacts entry screen is what CIRISAgent's
five-platform gate leans on; no tag it drives has changed.
Expand Down
6 changes: 3 additions & 3 deletions FSD/CSD/CSD-006-receipt.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# CSD-006 — The receipt (the template every CEG item asserts)

**CSD**: CSD-006 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the Locked Spec §2
**Flow**: `testing/flows/drafts/csd-006-receipt.yaml` (floor `>=0.5.225`) — driven on the first surface that binds the template (Contacts, CSD-005)
**Flow**: `testing/flows/csd-006-receipt.yaml` (floor `>=0.5.225`) — driven on the first surface that binds the template (Contacts, CSD-005)

```yaml csd:stage
stage: building
stage: testable
owner: CIRISClient
```

Expand Down Expand Up @@ -143,7 +143,7 @@ Bound per surface; CSD-005 §4 is the first instance.

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-006-receipt.yaml`, floor `>=0.5.225`, `fixture: two_node`). The two-node fixture (`testing/gate/two_node.py`) seeds a contact, and the flow opens `btn_receipt_${PEER_KEY_ID}` and asserts all five facts, the wire dimension and the wire rule (`chat:`). Run locally on the Linux desktop leg 2026-09-28 (candidate 0.5.224 checked as 0.5.225, node v0.5.217): 5/6 passed, the grant-less step skipped as designed because the node sends the grant. Not yet run on the other four legs; promotes when the floor is met and it runs on the matrix.
**`testable`** since the five-platform run 36775704425 (2026-09-30, `flows/matrix-0.5.225` at efdac2a2, node v0.5.217): the flow (`testing/flows/csd-006-receipt.yaml`, floor `>=0.5.225`, `fixture: two_node`) passed on all five legs — Linux, macOS and Windows desktop, the Android emulator and the iOS simulator. What follows is how it got there. The two-node fixture (`testing/gate/two_node.py`) seeds a contact, and the flow opens `btn_receipt_${PEER_KEY_ID}` and asserts all five facts, the wire dimension and the wire rule (`chat:`). Linux desktop leg run locally the way `five-platform-live-qa.yml` runs it (2026-09-29, candidate 0.5.225, node v0.5.217, `--flows testing/flows`, the two-node fixture): **5/6 passed, 1 skipped** — the seeded row's hamburger, all five envelope rows, the wire dimension, the rule row off the wire (`chat:` among the grant's prefixes) and the close; the grant-less step skipped as designed (the node sends the grant). On the matrix run of the same day (36588619656) every desktop leg failed this flow for csd-092's open contact-code card, since fixed (`cleanup:`). Not yet run on the other four legs. On the second matrix run (36600766576) it passed 6/6 on Linux and failed on macOS at its first step: `contacts_row_${PEER_KEY_ID}` was composed but below the fold, under the add card csd_005 had left open with a refusal, on a screen the harness cannot scroll (People's list is a LazyColumn with no `testableVerticalScroll`). csd_005's `cleanup:` now closes the card, and the runner says "composed but off screen after scrolling" with what `/scroll` answered, rather than "not on screen".

A card CSD that binds this template asserts `visible:` on all five `receipt_*`
tags after clicking its `btn_receipt_<id>`; a card whose rows are furniture
Expand Down
6 changes: 3 additions & 3 deletions FSD/CSD/CSD-008-notes-to-self.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

**CSD**: CSD-008 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the Locked Spec, B3 ("Files holds files") and B4 (Just me)
**Pairs with**: CSD-007 (Files: the drive plane these notes are rows of) · CSD-107 (Where is this file — each note's receipt opens it) · CSD-010 (Interact: the other card in Just me › Chats, when an agent is attached)
**Flow**: `testing/flows/drafts/csd-008-notes-to-self.yaml` (staged; floor `unreleased`)
**Flow**: `testing/flows/csd-008-notes-to-self.yaml` (floor `>=0.5.225`)

```yaml csd:stage
stage: building
stage: testable
owner: CIRISClient
```

Expand Down Expand Up @@ -88,7 +88,7 @@ The new note is **not** listed under Files (CSD-007: `DriveEntry.isNote`).

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-008-notes-to-self.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
**`testable`** since the five-platform run 36775704425 (2026-09-30, `flows/matrix-0.5.225` at efdac2a2, node v0.5.217): the flow (`testing/flows/csd-008-notes-to-self.yaml`, floor `>=0.5.225`) passed on all five legs — Linux, macOS and Windows desktop, the Android emulator and the iOS simulator. What follows is how it got there. Linux desktop leg run locally the way `five-platform-live-qa.yml` runs it (2026-09-29, candidate 0.5.225, node v0.5.217, `--flows testing/flows`, the two-node fixture): **2/2 passed**. On the matrix run of the same day (36588619656) it passed on Linux and could not start on macOS — `circle_agent -> tab_chats` landed on Rooms because the tab was clicked before the circle hop had landed (a node client signs in under Neighbours); the runner now verifies each hop against `/state`. Not yet run on the other four legs since.

**Verified live** (desktop, scratch ciris-server 0.5.215, 2026-09-24): writing
a note from the UI and reading it back from `/v1/notes`; a readable note
Expand Down
2 changes: 1 addition & 1 deletion FSD/CSD/CSD-032-network-identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ expect:

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-032-network-identity.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-032-network-identity.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97). **Floor left `unreleased` on the 0.5.225 run (2026-09-29):** the flow names `federation_id_card_not_on_this_node` (ReadFailureBlock builds `${tagPrefix}_not_on_this_node`). Real in 0.5.225, but built by interpolation, which the flow tag check (`testing/test_flows.py::_client_tag_strings`: whole literals and `$`-headed prefixes only) cannot see; a promoted flow naming them goes red at the keyboard. The fix is in that check, not the flow.

**Platforms.** All five; the bare-node variant on desktop and Android.

Expand Down
4 changes: 2 additions & 2 deletions FSD/CSD/CSD-033-network-peers.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**CSD**: CSD-033 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the route map (PR #111): a screen with routes and no CSD
**Covers**: `Screen.NetworkPeers` (`ui/screens/federation/NetworkPeersScreen.kt` + `viewmodels/NetworkPeersViewModel.kt`)
**Reads with**: **CSD-104** (a peer row opens `Screen.NetworkPeerDetail`: trust, appearance and the short-code ceremony live there, not here), CSD-046 (the same peer set drawn as a graph), CSD-051 (the hub)
**Flow**: `testing/flows/drafts/csd-033-network-peers.yaml` (floor `unreleased`)
**Flow**: `testing/flows/drafts/csd-033-network-peers.yaml` (floor `>=0.5.225`)

```yaml csd:stage
stage: building
Expand Down Expand Up @@ -116,7 +116,7 @@ expect:

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-033-network-peers.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-033-network-peers.yaml`, floor `>=0.5.225`); promotes to `testable` when it runs on the matrix. **Not moved to `testing/flows/` on the 0.5.225 run (2026-09-29):** `Screen.NetworkPeers` is flow-only — `nav_map` derives no hop to it, so the runner only waits for it after sign-in lands on Contacts, and the flow would be `cannot-start` (red) on every leg. To move it: start on LayerGlobalCommons (which has a hop) and tap `tile_federation_peers`, as csd-047 does.

**Platforms.** All five. The add-by-code path needs an agent; the bare-node leg
asserts the sheet's "not on this node" copy instead.
Expand Down
2 changes: 1 addition & 1 deletion FSD/CSD/CSD-036-network-ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ That second block was written before the fix and failed; it now passes.

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-036-network-ops.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-036-network-ops.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97). **Floor left `unreleased` on the 0.5.225 run (2026-09-29):** the flow names `netops_not_on_this_node` (ReadFailureBlock builds `${tagPrefix}_not_on_this_node`). Real in 0.5.225, but built by interpolation, which the flow tag check (`testing/test_flows.py::_client_tag_strings`: whole literals and `$`-headed prefixes only) cannot see; a promoted flow naming them goes red at the keyboard. The fix is in that check, not the flow.

**Platforms.** All five. The node-only variant needs the run-without-AI build,
which is exactly where the defect showed.
Expand Down
2 changes: 1 addition & 1 deletion FSD/CSD/CSD-040-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ itself; the fix landed (2026-09-28) and the block now asserts the sentence.

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-040-storage.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-040-storage.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97). **Floor left `unreleased` on the 0.5.225 run (2026-09-29):** the flow names `storage_disk_not_on_this_node` (ReadFailureBlock builds `${tagPrefix}_not_on_this_node`). Real in 0.5.225, but built by interpolation, which the flow tag check (`testing/test_flows.py::_client_tag_strings`: whole literals and `$`-headed prefixes only) cannot see; a promoted flow naming them goes red at the keyboard. The fix is in that check, not the flow.

**Platforms.** All five. The Postgres-only variant is a server-side fixture, not
a client platform, and belongs in CIRISServer's matrix; this flow only needs the
Expand Down
2 changes: 1 addition & 1 deletion FSD/CSD/CSD-045-node-self-standing.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ arrives anyway.

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-045-node-self-standing.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-045-node-self-standing.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97). **Floor left `unreleased` on the 0.5.225 run (2026-09-29):** the flow names the ConfirmSheet's `sheet_self_act`, `self_act_fact_1..3`, `btn_self_act_confirm` / `_cancel` and OwnerDelegationPicker's `input_self_delegation_id`, `opt_self_owner_delegation_0`, `text_self_no_owner_delegation` (every one built from `tagPrefix`). Real in 0.5.225, but built by interpolation, which the flow tag check (`testing/test_flows.py::_client_tag_strings`: whole literals and `$`-headed prefixes only) cannot see; a promoted flow naming them goes red at the keyboard. The fix is in that check, not the flow.

**Platforms.** All five, against a claimed node with an owner session. The
with-AI legs exercise the node URL, not the agent port. The delegation-supplied
Expand Down
4 changes: 2 additions & 2 deletions FSD/CSD/CSD-046-network-trust-graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**CSD**: CSD-046 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the route map (PR #111): two screens with routes and no CSD
**Covers**: `Screen.NetworkTrustGraph` (`ui/screens/federation/NetworkTrustGraphScreen.kt` + `viewmodels/federation/NetworkTrustGraphViewModel.kt`). **`Screen.NetworkMap` is retired into it** (below).
**Reads with**: CSD-033 (the same peers as a list), CSD-104 (tapping a node opens the peer detail), CSD-051 (the hub)
**Flow**: `testing/flows/drafts/csd-046-network-trust-graph.yaml` (floor `unreleased`)
**Flow**: `testing/flows/drafts/csd-046-network-trust-graph.yaml` (floor `>=0.5.225`)

```yaml csd:stage
stage: building
Expand Down Expand Up @@ -93,7 +93,7 @@ expect:

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-046-network-trust-graph.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-046-network-trust-graph.yaml`, floor `>=0.5.225`); promotes to `testable` when it runs on the matrix. **Not moved to `testing/flows/` on the 0.5.225 run (2026-09-29):** `Screen.NetworkTrustGraph` is flow-only — `nav_map` derives no hop to it, so the runner only waits for it after sign-in lands on Contacts, and the flow would be `cannot-start` (red) on every leg. To move it: start on LayerGlobalCommons and tap its trust-graph tile, as csd-047 does.

**Platforms.** All five; the canvas has no per-vertex tags, so the populated
assertion is the canvas and the count is not assertable (the list, CSD-033,
Expand Down
6 changes: 3 additions & 3 deletions FSD/CSD/CSD-047-network-content.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
**CSD**: CSD-047 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the route map (PR #111): a screen with routes and no CSD
**Covers**: `Screen.NetworkContent` (`ui/screens/federation/NetworkContentScreen.kt` + `viewmodels/federation/NetworkContentViewModel.kt`)
**Reads with**: CSD-051 (the hub), CSD-033 (the peer list it picks from), `PENDING-CSD-007` (Files, where a directory of what can be fetched would live; CIRISServer#651)
**Flow**: `testing/flows/drafts/csd-047-network-content.yaml` (floor `unreleased`)
**Flow**: `testing/flows/csd-047-network-content.yaml` (floor `>=0.5.225`)

```yaml csd:stage
stage: building
stage: testable
owner: CIRISClient
```

Expand Down Expand Up @@ -108,7 +108,7 @@ expect:

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-047-network-content.yaml`, floor `unreleased`, `fixture: two_node`): it enters from the hub's `tile_federation_content` and picks `peer_pick_row_${PEER_NODE_KEY_ID}`, the peer the fixture admitted. It has NOT run: besides the floor, the runner cannot reach its first screen on this build — nav_map's hop to LayerGlobalCommons (`circle_global_commons -> tab_rules -> nav_epistemic_layer_global_commons`) stops on CircleTab with the last tag never appearing (Linux desktop, 2026-09-28). A real fetch still needs a digest the peer holds, which the fixture does not seed.
**`testable`** since the five-platform run 36775704425 (2026-09-30, `flows/matrix-0.5.225` at efdac2a2, node v0.5.217): the flow (`testing/flows/csd-047-network-content.yaml`, floor `>=0.5.225`, `fixture: two_node`) passed on all five legs — Linux, macOS and Windows desktop, the Android emulator and the iOS simulator. What follows is how it got there. It enters from the hub's `tile_federation_content` and picks `peer_pick_row_${PEER_NODE_KEY_ID}`, the peer the fixture admitted. Linux desktop leg run locally the way `five-platform-live-qa.yml` runs it (2026-09-29, candidate 0.5.225, node v0.5.217, `--flows testing/flows`, the two-node fixture): **4/4 passed** — the Content tile (below the fold; the runner now scrolls to an off-screen control), the peer search, the fixture's peer row, the digest step and its refusal of a bad digest. On the matrix run of the same day (36588619656) it could not start on any desktop leg: the tab was clicked before the circle hop had landed, so Everyone › Rules was never shown; fixed in the runner. A real fetch still needs a digest the peer holds, which the fixture does not seed.

**Platforms.** All five, as the node's owner. A real fetch needs a second node
holding a known digest; the matrix stands one up.
Expand Down
4 changes: 2 additions & 2 deletions FSD/CSD/CSD-048-network-interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**CSD**: CSD-048 · **Standard**: CSD/3 (`CSD.md`) · **Origin**: the route map (PR #111): a screen with routes and no CSD
**Covers**: `Screen.NetworkInterfaces` (`ui/screens/federation/NetworkInterfacesScreen.kt` + `viewmodels/federation/NetworkInterfacesViewModel.kt`)
**Reads with**: **CSD-049** (the Queue tile: the same `GET /v1/federation/metrics` snapshot, projected per plane instead of per medium — two doors, see §6), CSD-051 (the hub)
**Flow**: `testing/flows/drafts/csd-048-network-interfaces.yaml` (floor `unreleased`)
**Flow**: `testing/flows/drafts/csd-048-network-interfaces.yaml` (floor `>=0.5.225`)

```yaml csd:stage
stage: building
Expand Down Expand Up @@ -96,7 +96,7 @@ expect:

## 5. QA plan

Spec complete and flow written (`testing/flows/drafts/csd-048-network-interfaces.yaml`, floor `unreleased`); promotes to `testable` when the floor is no longer `unreleased` and the flow runs on the matrix (#97).
Spec complete and flow written (`testing/flows/drafts/csd-048-network-interfaces.yaml`, floor `>=0.5.225`); promotes to `testable` when it runs on the matrix. **Not moved to `testing/flows/` on the 0.5.225 run (2026-09-29):** `Screen.NetworkInterfaces` is flow-only — `nav_map` derives no hop to it, so the runner only waits for it after sign-in lands on Contacts, and the flow would be `cannot-start` (red) on every leg. To move it: start on LayerGlobalCommons and tap its interfaces tile, as csd-047 does.

**Platforms.** All five. A LoRa or Bluetooth row needs hardware; the matrix
asserts tcp.
Expand Down
Loading
Loading