11 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created
| phase | slug | status | nyquist_compliant | wave_0_complete | created |
|---|---|---|---|---|---|
| 13 | aiui-functional-conversational-node-control-and-content-surf | draft | false | false | 2026-08-03 |
Phase 13 — Validation Strategy
Per-phase validation contract for feedback sampling during execution. Seeded from
13-RESEARCH.md§ Validation Architecture. Task IDs are filled in by the planner.
Test Infrastructure
This phase spans three test surfaces in two repositories.
| Property | Value |
|---|---|
| Framework (Rust) | cargo test — in-tree unit/integration tests (precedent: swarm/payment.rs #[tokio::test], pine_ha.rs #[test]) |
| Framework (neode-ui) | Vitest 3.1 — neode-ui/package.json "test": "vitest run" |
| Framework (AIUI repo) | ⚠️ UNCONFIRMED — packages/app/src/__tests__/ and composables/__tests__/ exist (contentExtraction.test.ts, useAI.test.ts) but the test command was not verified. Wave 0 must confirm before any wave depends on it. |
| Config file | core/Cargo.toml (Rust) · neode-ui/vitest.config.ts (frontend) |
| Quick run command | cd core && cargo test --package archipelago assistant:: · cd neode-ui && npx vitest run src/services/__tests__/contextBroker.test.ts |
| Full suite command | cd core && cargo test · cd neode-ui && npm run test |
| Estimated runtime | Rust full suite ~minutes; Vitest targeted ~seconds |
Build gotcha (CLAUDE.md): if cargo test hits rust-lld: undefined hidden symbol, that is incremental-cache corruption — rebuild with CARGO_INCREMENTAL=0. Not a real failure.
Sampling Rate
- After every task commit: the quick-run command for the touched module (
cargo test assistant::, or the specific Vitest file) - After every plan wave: full
cargo test+npm run test(neode-ui) + AIUI's own test command (once confirmed in Wave 0) - Before
/gsd-verify-work: full suite green and the AIUI-06 on-device pass on archi-dev-box (desktop + mobile) - Max feedback latency: targeted Vitest < 30s; Rust module tests < 120s
Per-Task Verification Map
Requirement-level map seeded from research. The planner fills Task ID / Plan / Wave / Threat Ref columns as it decomposes; every row below must end up owned by at least one task.
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|---|---|
| TBD | TBD | TBD | AIUI-01 | — | Typed chat request executes a real read-only tool ("how much space is left" → system.disk-status) and returns the real result |
integration (Rust) | cargo test assistant::tests::disk_status_tool_executes |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-01 | D-07/D-11 | A write request ("restart bitcoin") produces a pending confirmation, never an executed action, until the human confirms | integration (Rust) + component (Vue) | cargo test assistant::tests::destructive_tool_requires_confirm; npx vitest run src/services/__tests__/toolConfirm.test.ts |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-01 / AIUI-04 | Phase-10 D-01..D-04 | An unauthenticated caller cannot reach any new assistant.* RPC method |
integration (Rust) | cargo test rpc::middleware::tests::assistant_methods_require_session |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-04 | live exposure | /aiui/api/claude/ and /aiui/api/openrouter/ are no longer reachable without a session (see Manual-Only + note below) |
integration/shell | curl -s -o /dev/null -w '%{http_code}' http://<node>/aiui/api/claude/ returns 401/403 with no cookie |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-02 | D-16 | A conversational settings change is scoped to a granted permission category and refused when not granted | unit (Rust) | cargo test assistant::tools::tests::settings_tool_respects_category_grant |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-04 | D-10 | Peer-supplied text inside untrusted-content delimiters cannot escalate tool authority; an injected "restart bitcoin" still requires a human confirm naming the real action | unit (Rust) | cargo test assistant::tests::injected_instruction_does_not_grant_authority |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-03 | — | content.* RPC data renders in FilmGrid/SongGrid through the new adapter (pins the shape mismatch found in research) |
unit (Vue/TS) | npx vitest run src/composables/__tests__/archyContentAdapter.test.ts |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-03 | — | Audio routes to the global bottom-bar player, never the lightbox (regression-pins the rule enforced in 5 call sites) | unit (Vue/TS) | npx vitest run src/composables/__tests__/useAudioPlayer.test.ts |
⚠️ partial | ⬜ pending |
| TBD | TBD | TBD | AIUI-05 | D-15 | Build enforces VITE_BASE_PATH=/aiui/; script exits non-zero if unset |
shell/CI | scripts/build-aiui.sh (new) |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-05 | D-15 | Post-deploy check fetches a live asset over HTTP rather than trusting a directory listing | shell | curl a hashed asset resolved via sw.js, assert 200 + content |
❌ W0 | ⬜ pending |
| TBD | TBD | TBD | AIUI-06 | — | Embedded iframe on archi-dev-box, desktop + mobile | manual | N/A | — | ⬜ pending |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
Wave 0 Requirements
core/archipelago/src/assistant/+ its#[cfg(test)]module — the tool-calling loop is net-new; zero existing coverageneode-ui/src/services/__tests__/toolConfirm.test.ts— new confirm-flow coverage, extending thecontextBroker.test.tspatternneode-ui/src/composables/__tests__/archyContentAdapter.test.ts— pins theContentItem→Film/Song/Podcastmappingscripts/build-aiui.sh(or equivalent) — does not exist; D-15'sVITE_BASE_PATHenforcement + commit-pinning have no automated check today- Confirm AIUI's own test command before any wave assumes Vitest parity — unverified in research
- Keep green:
contextBroker.test.ts,chatAiuiEmbed.test.ts
Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|---|---|---|---|
| Embedded AIUI works in the real iframe | AIUI-06 | Real-device rendering in the actual embed context; dev:mock does not reproduce it |
Load neode-ui Chat view on archi-dev-box, desktop and mobile viewport; exercise a read tool, a confirmed write, and a content grid. Scope (D-13): the control and content tracks are blocking here; the music view is 13-15 step 7b, recorded as pass, gap or deferred and never blocking |
| Frontend bundle actually shipped | AIUI-05 | Node assets/ is a never-pruned graveyard — a disk grep reports "deployed" before the deploy |
Resolve live chunks via sw.js, fetch over HTTP, grep the fetched bytes for the new string |
| Confirm dialog is un-spoofable by the iframe | AIUI-04 / D-11 | Anti-spoofing is a visual/trust property of the host chrome | Verify the dialog renders outside the iframe, Teleports to body, full-screen backdrop, text drawn from the node's description — not model-authored |
| Routstr pays a live request | D-04 / D-05 | Research confidence on the Routstr protocol is MEDIUM — cited from docs, never run against a live provider | Spike against a real provider before the integration is trusted; budget ceiling must hard-stop |
Edge-Probe Reconciliation
The audit trail for the deterministic edge probe, counted against the plan files rather than asserted. An earlier summary claimed "5 truths + 4 unclassified = 9, nothing dropped"; that total was right by coincidence and wrong by composition, because it omitted the backstop scalar and silently absorbed three planner-authored edges into the probe's own count. The real numbers:
| Line | Count | Where |
|---|---|---|
| Requirements probed | 6 | AIUI-01 … AIUI-06 |
Probes resolved covered |
2 | AIUI-01, AIUI-03 |
Probes returned unclassified — flagged, never auto-resolved and never auto-backstopped |
4 | AIUI-02 → 13-05 · AIUI-04 → 13-09 · AIUI-05 → 13-09 · AIUI-06 → 13-15 |
| Probe-surfaced findings authored as covered truths | 5 | 1 in 13-01 (AIUI-01 concurrency) · 4 in 13-06 (AIUI-03 adjacency, empty, ordering, concurrency) |
Probe-surfaced findings authored as verification: backstop scalars |
1 | 13-01 — the two-tab confirmation-nonce case |
| Probe findings total | 6 covered + 4 unclassified = 10 | 5 truths + 1 backstop + 4 flagged |
| Planner-authored edge truths — not probe output | 3 | 13-07 — concurrency, ordering and empty re-applied to the persisted music index, tagged — authored, not probe-surfaced |
| Edge-tagged truths across all plans | 8 | 1 (13-01) + 4 (13-06) + 3 (13-07) |
| Edge entries across all plans, incl. the backstop scalar | 9 | the 8 above + 13-01's backstop |
Two numbers are easy to conflate and are deliberately kept apart here: 10 probe findings
(what the probe produced) and 9 edge entries in the plan files (what was written, including
three authored edges the probe never surfaced and excluding the four unclassified probes, which
are prose in <flagged_assumptions> rather than truths). Nothing was dropped in either
direction — every one of the 6 probes is accounted for, and every edge-tagged truth states
whether it came from the probe or from the planner.
Also verified and unchanged: the 4 unclassified entries sit under <flagged_assumptions> and
are never promoted to must_haves.truths; the 3 prohibitions in 13-08, 13-12 and 13-14 are
flat scalars under prohibitions, never under truths, and carry no check_* keys.
Open Questions Blocking Full Validation
Carried from 13-RESEARCH.md § Open Questions — each needs a planner decision, and two change what "validated" even means:
- The port-3142 proxy —
/aiui/api/claude/and/aiui/api/openrouter/are proxied with no session gate (image-recipe/configs/nginx-archipelago.conf, verified). Anyone reaching the node's web port can spend the owner's API budget. Removed, gated, or superseded by D-01's node-side loop? - Iframe sandbox mechanism — AIUI is same-origin today, no
sandboxattribute, permissive CSP. AIUI-04's "sandboxed by construction" is currently a code-discipline convention, not browser-enforced. Attribute, CSP, or accepted-and-documented risk? - Routstr protocol accuracy — needs a spike against a live provider before it is load-bearing.
- RBAC integration — should new
assistant.*RPCs go through the existingrole.can_access()check?
Validation Sign-Off
- All tasks have
<automated>verify or Wave 0 dependencies - Sampling continuity: no 3 consecutive tasks without automated verify
- Wave 0 covers all MISSING references
- No watch-mode flags
- Feedback latency < 120s
- AIUI repo test command confirmed
nyquist_compliant: trueset in frontmatter
Approval: pending