Persists the 17-item session task list so it can be rebuilt in a fresh session (the task tool is session-scoped and would otherwise evaporate), with what shipped and what each remaining item actually is. Records the findings that change expectations rather than leaving them to be rediscovered: the 16 federated peers are not serving content so peers_reached 0 is correct, IndeeHub's catalogue is genuinely empty, two AI permission stores existed for the same ten categories, and tailscaled owns :443 so nginx must bind LAN addresses explicitly or it fails EADDRINUSE and silently keeps the old config. STATE.md's stopped_at points at it, so /gsd-resume-work lands correctly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
36 KiB
gsd_state_version, milestone, milestone_name, current_phase, current_phase_name, status, stopped_at, last_updated, last_activity, last_activity_desc, progress
| gsd_state_version | milestone | milestone_name | current_phase | current_phase_name | status | stopped_at | last_updated | last_activity | last_activity_desc | progress | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1.0 | v1.8.0 | milestone | 13 | aiui-functional-conversational-node-control-and-content-surf | executing | 2026-08-07. READ .planning/RESUME-2026-08-07-aiui-demo.md FIRST — it carries the 17-item task list to rebuild in the session task tool, what shipped, and the findings. AIUI IS BEING DEMOED SOON + a clean ISO must be cut: prioritise #16 (surface stays empty while chat prints correct prose), #15 (surface header overlaps the close button; left heading shows the LAST search, should say Loading), #9 (surfaces not prose), #17 (ISO, UNBUNDLED=1 or it silently builds the wrong variant). DONE+DEPLOYED: gate no longer deletes apps Authorization header (broke every Nostr signer), gate no longer 401s credential-less PWA manifests, AI grants unified into ONE store (two existed for the same ten categories — that, not persistence, is why toggling Settings never helped the assistant), content-card description pairing, IndeeHub relay 502, content_list scopes + 2 RPCs, progressive content load, Mesh TDZ crash, peer-browse cap rebuilt as Cloud fan-out, cert section layout, LAN HTTPS (tailscaled owns :443 so nginx must bind LAN addrs explicitly). KEY FINDING: the 16 federated peers are NOT serving content — FIPS is healthy but 14 dials fail, so peers_reached 0 is CORRECT and no UI work fixes it; IndeeHub catalogue is genuinely empty. Phase 13: 14/15, only 13-15 left; operator verified checks 1, 3 and 4 — check 2 is the holdout because no film content exists here. | 2026-08-07T00:00:00.000Z | 2026-08-06 | 13-14 complete (18-case adversarial eval harness EV-01..EV-18, ScriptedBackend-driven, offline/zero-footprint; E-02 confirmation-copy sign-off operator-approved with three verbatim dialog texts; E-09 naive-user comprehension study recorded as an open residual, not run) |
|
Project State
Project Reference
See: .planning/PROJECT.md (updated 2026-07-29)
Core value: A third-party developer can publish an app via the signed/decentralized registry and a user can install it on their node — manifest-driven, rootless, secure, robust. Current focus: Phase 13 — aiui-functional-conversational-node-control-and-content-surf
Current Position
Phase: 13 (aiui-functional-conversational-node-control-and-content-surf) — EXECUTING Plan: 14 of 15 complete (13-01..13-14) — next: 13-15 Status: Ready to execute Last activity: 2026-08-06 — 13-14 complete (18-case adversarial eval harness EV-01..EV-18; E-02 confirmation-copy operator-approved; E-09 comprehension study recorded as an open residual)
Progress: [█████████░] 87%
Performance Metrics
Velocity:
- Total plans completed: 11
- Average duration: —
- Total execution time: —
By Phase:
| Phase | Plans | Total | Avg/Plan |
|---|---|---|---|
| 02 | 11 | - | - |
| Per-Plan Metrics: |
| Plan | Duration | Tasks | Files |
|---|---|---|---|
| Phase 02 P01 | 100min | 3 tasks | 5 files |
| Phase 02 P03 | 45min | 3 tasks | 5 files |
| Phase 02 P02 | 105min | 3 tasks | 11 files |
| Phase 02 P04 | 150min | 3 tasks | 12 files |
| Phase 02 P05 | 50min | 2 tasks | 8 files |
| Phase 02 P06 | 73min | 2 tasks | 7 files |
| Phase 02 P07 | 75min | 3 tasks | 5 files |
| Phase 02 P08 | ~190min | 3 tasks | 4 files |
| Phase 02 P09 | 130min | 3 tasks | 3 files |
| Phase 02 P10 | 55min | 2 tasks | 3 files |
| Phase 02 P11 | ~150min | 3 tasks | 8 files |
| Phase 01 P01 | n/a-continuation | 2 tasks | 1 files |
| Phase 13 P07 | ~3h45m | 2 tasks | 5 files |
| Phase 13 P08 | ~7h45m (elapsed, w/ session restart) | 3 tasks | 10 files |
| Phase 13 P10 | ~2h45m | 2 tasks | 10 files |
| Phase 13 P11 | 27min | 3 tasks | 12 files |
| Phase 13 P12 | ~4h35m (shared-box compute contention) | 3 tasks | 9 files |
| Phase 13 P13 | ~4h (shared-box compute contention, session crash-recovered mid-Task-3) | 3 tasks | 6 files |
| Phase 13 P14 | ~1h10m | 3 tasks | 4 files |
Accumulated Context
Roadmap Evolution
- Phase 1 added (2026-07-29): Federation & Mesh Hardening — user-directed top priority (node removal/sync issues, mesh attachment parity incl. demo); prior phases shifted down
- Phase 2 added (2026-07-29): UI Performance — slow tab switches and secondary screens; prior phases shifted down
- FED-05 added to Phase 1 (2026-07-29): inter-node Lightning channel-opening UX (share node URI, pick trusted/federated nodes by hostname, request channels with public nodes); UI tested on :8100 dev preview against archi-dev before deploy
- FED-06 added to Phase 1 (2026-07-29): on-brand paid-tick animation — screensaver ring + EQ segments (reuse ScreensaverRing.vue compact) replacing the success burst in SendBitcoinModal.vue
- Phase 9 added (2026-07-30): BotFights Platform Upgrade — native nostr signer login, unified AI bot-setup prompt replacing docs page, shared public match endpoint on VPS2 (all nodes see all fighters), registry/manifest update. Independent of Phases 1–8.
- Phase 13 added (2026-08-03): AIUI — Conversational Node Control & Content Surfaces. User-directed: AIUI is embedded and styled but non-functional — chat cannot act on the node, content surfaces are unwired. Scope is (a) Pine's human-language intent→action capability reachable from typed chat, (b) conversational settings, (c) peer files / music / IndeeHub movies / node content rendered live, (d) a user-granted capability sandbox keeping keys, secrets and identity material away from the browser and the model — the user called this out explicitly as non-negotiable. Spans two repos: this one and
git.tx1138.com/lfg2025/AIUI(branchdevelopment, clone at~/Projects/AIUI). Appended, not inserted — numeric position is append order, not priority. - Phase 10 added (2026-08-01): Key-Material Hardening — KEY-01/F-01 (Critical: unauthenticated
seed.generate/seed.restoreoverwrite a live node's identity keys), KEY-02/F-03 (fail-open first-boot secret regeneration over a fleet-shared rootfs), KEY-03/F-13 (BIP-84 private key imported into Bitcoin Core), KEY-04 (on-node verification of the audit's UNVERIFIED checklist). Sourced fromdocs/security/ENTROPY-SEED-AUDIT-2026-07-31.md(quick task 260731-upz). Appended rather than inserted to avoid renumbering a roadmap with concurrent uncommitted edits — numeric position is append order, not priority; F-01 is Critical and live on the fleet.
Decisions
- [Phase 13, D-19 (2026-08-03)]: AIUI's source migrated into this repo at
aiui/, viagit subtreewith its full 230-commit history (7ba3109b, from AIUIdevelopment@e30ac1d). Supersedes D-15's two-repo premise and voids D-18 entirely. Retires the recurring "AIUI commit stranded local-only" failure (windows 4 and 17) —e30ac1dcame across in the import and is now pushed. D-17 (standalone mode) is unaffected: archy has no rootpackage.json, so AIUI's pnpm/turbo workspace does not collide. Consequence: plans 13-06, 13-09, 13-11 still target/home/archipelago/Projects/AIUI/absolute paths and must be re-planned before wave 2; 13-09'sscripts/aiui.pindeliverable is now meaningless for an in-repo directory. - [Phase 13, wave 1]: Recovered from a broken-pipe interruption that left 13-01 and 13-02 executor work uncommitted in orphaned worktrees. Both were checkpointed verbatim before any agent touched them, then re-committed atomically per task by continuation executors (both chose
reset --soft+ recommit). 13-03 was already complete and was fast-forwarded in. - [Phase 13, execution mode]:
parallelization: false— this 4-core box thrashed (load 35-55, 15G/23G swap) running two worktree cargo builds concurrently alongside a live node (bitcoind/electrumx/lnd). Serial execution is strictly faster here. - [Phase 13, 13-04 / D-13 one-way half (2026-08-04, operator)]: Music entity model recorded in 13-MUSIC-MODEL.md BEFORE any node indexes a library — hybrid-identity ((source, canonical path) row key + lazily-backfilled content-hash dedupe column), derived-albums (albums/artists computed at read time, never stored rows), index-format-json (data_dir/music/index.json, content_server.rs precedent), sources = both OwnLibrary and Peer. MUSIC_SCHEMA_VERSION starts at 1; an older binary treats a newer-versioned index as absent (log + empty in-memory index, never overwrite) until an explicit reindex.
- [Phase 13, 13-04 Task 2 (2026-08-04, operator)]: lofty 0.24.0 approved through the blocking-human package-legitimacy gate ([ASSUMED] in 13-RESEARCH.md's audit); dep tree reviewed, no networking crates. Media-root confinement in extract_tags is a parameter (media_roots), checked via canonicalize before any file open (T-13-20).
Decisions are logged in PROJECT.md (10 locked ADRs in the <decisions> block + milestone decisions table). Recent decisions affecting current work:
- Milestone version = 1.8.0-alpha (decided 2026-07-08)
- Phase-3 Quadlet default-flip is gated on the second-node gate reporting clean (do fresh, never stage uncommitted)
- Workstream D (DHT distribution) deferred to v2 — design-only backlog
- Canonical manifest schema =
core/container/src/manifest.rs(code wins over spec doc) - [Phase ?]: Marketplace is the 02-02 tracer tab (worst-measured main tab, 2033ms revisit) matching the user's own 'often app store' complaint
- [Phase ?]: ContainerAppDetails.vue confirmed fully unreachable dead code (no importer, no route) — no serial-RPC-waterfall target exists in the measured D-09 surface set
- [Phase ?]: archi-dev-box UI password was unknown/undiscoverable from this environment — paused at a checkpoint:human-action rather than guessing or falling back to a mock baseline silently
- [Phase ?]: Purged the resource cache on logout via clearAll() + a generation guard, so no in-flight fetch from an ending session can repopulate memory or sessionStorage (T-02-02)
- [Phase ?]: AppDetails/MarketplaceAppDetails/OpenWrtGateway converted to per-item (or single-key) keyed useCachedResource; CloudFolder.vue's existing store-level cache left as-is (cloud.ts TTL gate is a follow-up, out of this plan's file scope)
- [Phase ?]: Wallet/send flow (SendBitcoinModal.vue) reported as an unplanned-item gap — named by findings as owned by 02-03 but not in files_modified; its cost is pure client-side remount, not a caching problem
- [Phase ?]: PERF-03 reverted to Pending in REQUIREMENTS.md after an initial mark-complete was premature — its own text requires real-node-hardware verification, which is 02-08's job (also declares PERF-03); 02-03 delivers the code-level portion only
- [Phase ?]: 02-02: DashboardRouterView final shape uses statically-named per-route KeepAlive wrapper components (dashboardViewWrappers.ts) with :include name-matching, restoring pre-restructure view-wrapper DOM/animations byte-for-byte after a checkpoint-caught regression
- [Phase ?]: 02-02: HARD RULE for rest of Phase 02 — perf work must be visually invisible; verify against the real dev preview before considering a checkpoint satisfied
- [Phase ?]: 02-02: app-catalog persist:true ttl 300000ms; bitcoin.prune-status persist:true ttl 30000ms — both explicit per T-02-01, no default relied on
- [Phase ?]: 02-02: PERF-02 reverted to Pending/In-Progress in REQUIREMENTS.md after an automated mark-complete run — PERF-02 also spans 02-04..02-07 (extending KeepAlive caching to every remaining main tab); this plan proves the architecture on the tracer tab only
- [Phase ?]: 02-04: KEEP_ALIVE_PATHS widened to every audited main tab (10 paths) derived from TAB_ORDER + /dashboard/discover; /dashboard/settings deliberately withheld — its child sections (SystemDangerZone reboot poll, several onMounted-only fetches) were never audited by this plan
- [Phase ?]: 02-04: onActivated is a documented no-op outside a KeepAlive boundary — every arm function now runs from both onMounted and onActivated (fresh-mount guards on Home/Web5/Mesh/Server avoid doubling first-load RPC cost); caught by CloudPeersRefresh.test.ts
- [Phase ?]: 02-04: useCachedResource.ts's onActivated no longer eagerly force-loads a never-fetched immediate:false resource, so tab-gated lazy data (Cloud.vue Paid Files/My Files) isn't force-loaded merely by its view entering the KeepAlive cache
- [Phase ?]: 02-04: AIUI blank-screen-and-loading symptom reported at Task 3 checkpoint diagnosed as pre-existing (local mock-backend dev mode sets VITE_AIUI_URL=http://localhost:5173 unconditionally with no AIUI repo checked out) — not a regression, left for 02-07 (Chat/AIUI) to address
- [Phase ?]: 02-05: mesh.refreshAll()/transport.fetchStatus() stay uncached at the store level (other callers need guaranteed-fresh reads); the useCachedResource wrapper around each lives in Mesh.vue instead, since Pinia's defineStore(id,setup) runs in a bare effectScope where onActivated() silently no-ops
- [Phase ?]: 02-05: FLAGGED - RESEARCH.md's premise that Mesh.vue owns a D3 force simulation is incorrect for this codebase (verified via grep); only NetworkMap.vue/Federation.vue has one. Task 2's D3 truths are vacuously satisfied; only the real Leaflet map lifecycle (MeshMap.vue, added to scope) was implemented
- [Phase ?]: 02-05: per-group TTL/persist table - mesh.refresh-all/federation-nodes/self-onion/self-did/contacts all persist:false (identity payload); transport-status persists (aggregate, non-identity); reachability groups get 10s TTL, identity groups 300s
- [Phase ?]: 02-06: RESEARCH A3 settled — none of Server's seven load-group loaders consumes another's result; concurrent fan-out is correct as-is
- [Phase ?]: 02-06: Five of Server's seven groups were already on useCachedResource from a pre-phase legacy commit (
ea254f63) with only composable defaults (30s TTL, persist:true) — this plan's work was explicit TTL/persist/dedup, not initial conversion; only loadDiskStatus was a genuinely uncached plain fetch - [Phase ?]: 02-06: Home's wallet composite does NOT share a cache key with Web5.vue's web5.lnd-info — sharing would either corrupt Web5's typed entry.data or fail to close the sessionStorage gap since Web5.vue's own hook (out of scope) defaults persist:true
- [Phase ?]: 02-06: homeStatus.refresh() wrapped by useCachedResource at Home.vue (the view), not inside the homeStatus Pinia store — defineStore(id,setup) runs in a bare effectScope where onActivated() silently no-ops, same finding as 02-05's Mesh.vue
- [Phase ?]: 02-07: AIUI source located mid-plan at git.tx1138.com/lfg2025/AIUI (base branch development, not stale main); AIUI-side D-14 commit
900c0b9initially local-only (anonymous push 403) then pushed/merged upstream onto development by the orchestrator using a user-supplied write token - [Phase ?]: 02-07: D-14a fixed via new ?chatExpanded param overriding chat.ts's chatCollapsed default (never persisted to localStorage); D-14b fixed via new ?mobileChat param re-asserting ChatPage.vue's mobileTab='chat' once on mount, guarding against module-singleton content-panel state surviving an internal AIUI remount
- [Phase ?]: 02-07: PERF-02 marked Complete in REQUIREMENTS.md — 02-02 through 02-07 extended KeepAlive/useCachedResource to every main tab, each dev-preview-verified against archi-dev-box per D-11
- [Phase ?]: 02-08: KEEP_ALIVE_MAX left at 6, now backed by an on-device memory reading (4 cycles, 11 tabs, JS heap fluctuating 10-21MB, no monotonic growth) rather than the FA-D estimate
- [Phase ?]: 02-08: archy-x250-dev offline for the entire plan (checked 3x); archi-dev-box (D-11's named target) is the only dev-pair node this phase reached
- [Phase ?]: 02-08: the harness's remount-probe field is confounded for main tabs once real KeepAlive keeps multiple instances alive simultaneously; corrected via an independent, reproduced-twice verification rather than editing the frozen 02-01 harness — revealed Server.vue genuinely does not survive a round-trip (open gap, not hidden)
- [Phase ?]: 02-08: a user-reported Cloud first-visit navigation regression was treated as release-blocking, not known-open, per explicit direction — root-caused to content.browse-peer's unbounded, untimed-enough per-peer RPC fan-out starving Chromium's connection pool; fixed via a concurrency cap + shortened timeout, verified 5/5, user-approved on-node
- [Phase ?]: 02-08: 4 other user-reported UX issues (Paid Files window.open, PiP not closing lightbox, missing loader on Paid Files item-open, PiP not surviving tab changes) classified as pre-existing (predate phase 2 via git history) and captured into UIFIX-04/05/06, not fixed
- [Phase ?]: 02-09: /dashboard/server's (and Web5's) 'genuinely remounts' reading was a proven probe-measurement artifact (generic .view-container selector can't disambiguate the foreground tab from other still-connected cached tabs) — confirmed via document.elementFromPoint() hit-test contradicting the naive verdict across device runs; no source change needed, pinned with vm.$.uid-based regression tests instead
- [Phase ?]: 02-09: committed neode-ui/e2e/perf/keepalive-remount-probe.spec.ts as a re-runnable, instrumented probe covering every KEEP_ALIVE_PATHS tab, replacing the ad-hoc 02-08 probe so this class of false positive cannot recur
- [Phase ?]: [Phase 2, gap closure 02-10]: Wallet/send-flow's timing regression cleared as environmental noise (re-measure at/below baseline); Discover/Server/Web5/AppDetails/OpenWrtGateway confirmed as real, phase-2-caused client-side render/reactivation regressions via 3-run dispersion + git bisection, recorded as accepted deviations (not fixed — deploy blocked mid-session by a shared-tree hazard with concurrent security-follow-up and BotFights sessions)
- [Phase 2, gap closure 02-11]: Real cause of the six regressions was NOT compute-bound render cost (CPU profile: 86-99% idle/program, <10% JS self-time everywhere) — it was three background pollers (useFleetData.ts 60s, FipsNetworkCard.vue 15s, Web5Monitoring.vue 30s) armed in onMounted and never disarmed once their owning views joined KEEP_ALIVE_PATHS in 02-04, invisible to that audit because it grepped the top-level view files, not the child composables they delegate to. Gated to onActivated/onDeactivated, mirroring 02-04's own established pattern. Fixed: web5 275ms (was 566ms baseline/1329ms regressed), server 574ms (was 738/1239), fleet 790ms (was 330/2631)
- [Phase 2, gap closure 02-11]: Discover (1389ms, worst remaining) has a SECOND, distinct cause: card-stagger/showStagger entrance-animation classes are baked into the DOM at first mount and never programmatically removed, so every KeepAlive detach/reattach cycle restarts the CSS animation on reactivation — replaying the full entrance cascade on every revisit. Confirmed via a diagnostic (DOM card count doubling transiently on every revisit) and an extended animation-event log. NOT fixed — blast radius spans 5+ files outside 02-11's scope (Apps.vue, Marketplace.vue, Home.vue, several Web5 sub-cards), needs its own real-device verification budget; recommended as a dedicated follow-up
- [Phase 2, gap closure 02-11]: openwrt-gateway unmeasurable in the final re-measure (Chromium "Target crashed" cascading from an unrelated surface, cloud-folder, earlier in the same harness run) — recorded as not-measurable, not written in as data. Separately confirmed the prior baseline/after/remeasure numbers were measuring a real, substantive disconnected-state UI (OpenWrtGateway.vue's h1 is unconditional; a "No router configured" RPC error deterministically renders a real Connect-to-Router form, not a blank/error page) — the six-surface regression count is not retracted, but the numbers reflect one specific code branch (no OpenWrt device has ever been connected to archi-dev-box)
- [Phase ?]: 01-01: record_peer_transport and update_node routed through FEDERATION_STORE_LOCK via *_inner; tombstone-write-failure test added; full-suite verify blocked by a concurrent agent's uncommitted install.rs edit (unrelated file, not fixed per scope boundary)
- [Phase ?]: UIFIX-02: connected-nodes card height tracks row sibling via xl:flex-1 xl:basis-0 (zero-basis flex-grow) instead of flex-auto, with an xl:min-h-[40rem] floor for a short sibling (discovery disabled), tuned from an initial 20rem guess per Dorian's live feedback
- [Phase ?]: 13-07: media_roots = filebrowser/Music + purchased-content (both D-13 sources as local roots); music.reindex incremental:true wires refresh_incremental to a production caller; one comparator everywhere with TrackId (source,path) tiebreak
- [Phase ?]: [Phase 13, 13-08]: System prompt rewritten to make the model call destructive tools directly rather than text-asking for confirmation — the original wording ('every write requires a human confirmation') read as 'collect consent in text first', which skipped the tool call and dropped the user's typed 'confirmed' into a void on the next stateless turn
- [Phase ?]: [Phase 13, 13-08]: CONFIRM_TIMEOUT raised 120s->300s and the full HTTP timeout chain (rpcClient, assistant.chat 420s, AIUI bridge 180s->430s) raised past it, so transport can no longer time out a human reading the confirm dialog before the confirm gate itself does
- [Phase ?]: [Phase 13, 13-08]: Declined actions remembered per-turn in ToolExecCtx, keyed by the same action_key the approval nonce binds; execute_tool refuses a re-ask for that exact action before the gate reopens, closing a retry loop where a declined action kept re-prompting (T-13-50 mechanized)
- [Phase ?]: [Phase 13, 13-10]: OllamaBackend leads the D-04 chain via POST /api/chat (never assist.rs's /api/generate); model_supports_tools() probes /api/show and process-caches the answer, turning AI-SPEC's qwen2.5-coder [ASSUMED] tool-capability note into a runtime fact; FallbackChain falls through to Claude on a transport error mid-turn, not just at initial selection
- [Phase ?]: [Phase 13, 13-10]: history.rs persists the full ChatMessage transcript per CallerScope-derived HistoryKey under data_dir, atomic (temp+rename) and 0600, with wallet/files-category tool-call arguments redacted before disk (verified against raw bytes, not just the struct); chat() persists but does not yet feed prior turns back into live model context (deliberately scoped out, needs Claude tool_use/tool_result id-pairing test budget as a follow-up)
- [Phase ?]: [Phase 13, 13-10]: detect_ollama() and its two containing modules bumped to pub(crate) (api/rpc/mod.rs, api/rpc/mesh/mod.rs, api/rpc/mesh/assistant.rs) so assistant::backends could reuse the existing Ollama probe rather than writing a second one; run_loop (loop_.rs) now returns (answer, full_history) instead of just the answer, both Rule-3 deviations structurally required by the plan's own stated intent
- [Phase ?]: 13-11: kind:'library' content:request routes to music.list-tracks (not content.) via a new contextBroker.ts fetchLibraryContent branch — Rule 2 deviation, contextBroker.ts's diff-clean acceptance criterion could not hold alongside genuine music. wiring (ContentItem has no artist/album/duration field at all)
- [Phase ?]: 13-11: closed the plan's GAP-FOUND must_have — useArchy.ts's init() now fires requestArchyContent + requestArchyLibrary automatically as a live init-time event, and useContentPanel.ts's setArchyContent opens the panel/sets tabs for non-empty content, instead of leaving the fetch merely callable with nothing in the UI ever invoking it (13-06's own documented Known Limitation)
- [Phase ?]: 13-12: wrap_untrusted's per-call token is drawn fresh from rand on every call (never a module constant) — a forged closing boundary using a guessed/fixed token can never match, defeating EV-11 by construction; no pattern-stripping filter added anywhere in assistant/ (D-10 rejects that approach by name)
- [Phase ?]: 13-12: assistant.chat's G-B3 rate limit is keyed by authenticated SESSION id (not client IP) via a new session_requests map on the existing EndpointRateLimiter — 13-AI-SPEC §6 is explicit that per-session, not per-IP, is the guardrail's own spec
- [Phase ?]: 13-12: screen_outbound (G-B1/G-B2) wired into backends/claude.rs's send() and the assistant.chat rate limit wired into api/rpc/assistant_chat.rs — both Rule 3 deviations outside their task's declared file list, since the plan's own stated behavior (run on the Claude leg / rate-limited per session) had no real call site otherwise
- [Phase 13, 13-13 Task 1 (2026-08-05, operator via AskUserQuestion)]: Routstr decision = proceed-docs-with-probe-first (0/9 protocol claims independently confirmed per 13-ROUTSTR-FINDINGS.md — no live provider was reachable during the 13-03 spike). Implemented against docs.routstr.com's cited shape (kind 38421,
Authorization: Bearer cashuA…, OpenAI-shape chat completions); the first live HTTP call to any provider doubles as the capability probe and fails loudly (real status/body, or "no choices array") on any wrong guess rather than silently misbehaving. D-04's chain is now complete: Ollama -> Claude -> Routstr - [Phase 13, 13-13]: D-05's budget ceiling (
AssistantBudget) is computed ONLY from persisted allowance_sats/spent_sats — never from anything model/tool/provider-influenced;BudgetExhausted(typed, anyhow-downcastable) stopsrun_loopwith a plain-language message, no retry/re-price/partial-spend/fallthrough. Verified load-bearing by fault injection: temporarily replacing the terminatingreturnwithcontinuemadezero_budget_stops_loop_without_retrygo red (8 retries to MAX_TURNS, generic error) before being restored - [Phase 13, 13-13]: egress.rs's message_is_turn_own (13-12's G-B2 check) was Claude-shape-only and would have silently stripped Routstr's OpenAI-shape system prompt + tool results out of every outbound request — fixed with explicit "system"/"tool"-role handling (Rule 1 bug, found while wiring screen_outbound into routstr.rs)
- [Phase ?]: [Phase 13, 13-14]: Task 3's E-02 sign-off was conducted via the orchestrator driving real node RPCs, with the operator reviewing the captured dialog texts directly and approving them; E-09's naive-user timed-comprehension protocol was NOT run and is recorded as an open residual carried forward, not force-passed under a lowered bar.
- [Phase ?]: [Phase 13, 13-14]: In-crate #[cfg(test)] eval module (assistant::evals) used instead of a tests/ integration target, since core/archipelago is bin-only with no [lib] — cargo test --package archipelago assistant::evals:: is the invocation; release-binary string grep confirms zero shipped footprint.
Pending Todos
- [blocker/ui] Keep FIPS/Tor pills on cloud files and show them on mobile (
.planning/todos/pending/2026-07-30-keep-fips-tor-pills-on-cloud-files-and-show-them-on-mobile.md) - [blocker/security] Fedimint gateway must not install with a pre-set password — tracked as FED-07 / Phase 1 gap plan (
.planning/todos/pending/2026-07-30-fedimint-gateway-must-not-install-with-preset-password.md) - [blocker/ui] Connected-nodes list must scroll at row-matched height, not grow to fit (
.planning/todos/pending/2026-07-30-connected-nodes-list-must-scroll-at-row-matched-height.md) - [blocker/ui] Onboarding tickbox hidden below fold on short screens — make it beautifully obvious (
.planning/todos/pending/2026-07-30-onboarding-tickbox-hidden-below-fold-on-short-screens.md) - [major/ui] Paid Files pictures open in browser tab, not the app lightbox — UIFIX-04 (
.planning/todos/pending/2026-07-30-peer-files-pictures-open-in-tab-not-lightbox.md) - [major/ui] PiP should close the lightbox with a fluid animation — UIFIX-05 (
.planning/todos/pending/2026-07-30-pip-should-close-lightbox-with-fluid-animation.md) - [major/ui] Missing loader states on slow opens — UIFIX-06 (
.planning/todos/pending/2026-07-30-missing-loader-states-on-slow-opens.md)
Blockers/Concerns
- [Phase 1] Federation tombstone fix touches trust code — fix carefully, re-verify with
tests/multinode/smoke.sh, don't patch blind - [Phase 3] Multinode gate on archy-x250-beta was launched 2026-07-01 (log on-node); verify outcome before re-running
- [Phase 5] Fleet registry flip awaits explicit user authorization + timing call
- [Phase 6] Strengthened ADR-009 validation may reject existing catalog apps — audit manifests before enforcement lands
- [Global] Live OTA fleet: deploy to the dev pair before any OTA; gate re-runs required after orchestrator changes; some verification is user/hardware-gated (radios, on-device tests)
- cloud.ts's navigate() needs a TTL gate to fully satisfy 'no new RPC within TTL' for CloudFolder.vue — currently always re-fetches on revisit (just doesn't block paint)
- [Phase 2, RESOLVED by 02-09]
Server.vue does not survive a tab round-trip despite KEEP_ALIVE_PATHS registration— retracted: proven a probe-measurement artifact (shared generic.view-containerselector couldn't disambiguate the foreground tab from other cached tabs), not a real defect. Server.vue's (and Web5.vue's) instance genuinely survives; pinned withvm.$.uid-based regression tests immune to the same ambiguity. Checkpoint approved on real hardware. - [Phase 2, RESOLVED by 02-11]
Timing regressions on Discover/Web5/Fleet/AppDetails/OpenWrtGateway— root cause found (three leaked background pollers, not compute-bound render cost) and fixed for web5/server/fleet, each proven with a real before/after number on archi-dev-box. AppDetails restored to at/near its own pre-phase-2 baseline (pre-existing per-mount cost, not a new defect). OpenWrtGateway not measurable this pass (browser crash); prior numbers stand with a data-integrity note (measuring a real disconnected-device UI, not an empty page). - [Phase 2, follow-up needed] Discover (1389ms, worst remaining named surface) has a second, evidenced, phase-2-caused defect: KeepAlive'd entrance-stagger animations (
card-stagger/showStagger) never get their class removed from the DOM after first play, so every reactivation replays the full CSS animation cascade. Fix requires touching 5+ files outside 02-11's scope (Apps.vue, Marketplace.vue, Home.vue, Web5Wallet.vue/Web5Identities.vue/Web5NodeVisibility.vue/Web5NostrRelays.vue) with its own real-device visual-regression verification budget (the same class of risk 02-02's original KeepAlive rollout hit on its first checkpoint attempt) — needs a dedicated follow-up plan, not squeezed into a gap-closure pass.
Quick Tasks Completed
| # | Description | Date | Commit | Directory |
|---|---|---|---|---|
| 260729-fw7 | improve mesh message hop graphic/animation: balanced desktop sizing, vertical mobile layout, archipelago branding | 2026-07-29 | ac09fc5d |
260729-fw7-improve-mesh-message-hop-graphic-animati |
| 260729-gjd | demo: indee.tx1138.com in app iframe (:2101 whole-origin proxy), auto nostr signer sign-in, IndeeHub pre-installed on fresh session | 2026-07-29 | d00ca624 |
260729-gjd-demo-make-indee-tx1138-com-work-in-the-a |
| 260729-hj1 | peer-files media batch: Wavlake paid tracks + purchases + dedupe + real photos (demo); lightbox/player open routing + free-image lightbox fix (both builds) | 2026-07-29 | f52c5407 |
260729-hj1-peer-files-media-batch-wavlake-paid-trac |
| 260729-je5 | connected-nodes list fills card height (constant footer gap); companion app skips demo intro | 2026-07-29 | d54517cf |
260729-je5-ui-fixes-connected-nodes-scrollable-list |
Deferred Items
| Category | Item | Status | Deferred At |
|---|---|---|---|
| Distribution | DIST-01 DHT/iroh backbone (workstream D) | v2 | 2026-07-29 |
| Fleet | FLEET-01 Bitcoin multi-version fleet OTA (user-gated) | v2 | 2026-07-29 |
| Fleet | FLEET-02 per-app deep health assertions (~34 apps) | v2 | 2026-07-29 |
| Fleet | FLEET-03 LUKS2 data-partition encryption | v2 | 2026-07-29 |
Release SHIPPED — v1.7.120-alpha (2026-08-03)
LIVE. signature PRESENT (did:key:z6Mkkid…q7ur), both assets HTTP 200 at exactly their manifest byte counts, tag pushed. Two release-process traps hit and documented in memory: create-release.sh commits the manifest BEFORE signing (fleet refuses unsigned), and gitea-vps2 is the SAME server as gitea-ai (vps2 token is dead).
Staging record (kept for the evidence trail)
Built from 4d67f56b (release profile, 15m15s, exit 0), deployed to archi-dev-box,
.bak rollback at /opt/archipelago/rollback/archipelago.bak.
Verified on the node: both security gates 401 unauthenticated from a non-loopback address; CORS origin-scoped; AIUI assets 200 AFTER the frontend rsync (the deploy that would have wiped a copied-file fix); mesh.lightning-peers/send-lightning-info answer correctly; system.stats host_secrets = per-node; served bundle sha256-matches the build on all three chunks; 31 containers up, none down, no restart loop.
NOT verified, deliberately: the new torrc SocksPort/SocksPolicy block. regenerate_torrc
only fires on a Tor services change, so the live torrc still reads only SocksPort 9050.
Gateway detection was proven in isolation (10.89.0.1 10.89.0.0/24; missing network exits
non-zero -> stays loopback-only). The change is INERT this release since bitcoind has no
-onion flag yet (Phase 12), so forcing a torrc regeneration would risk bouncing every
onion service for zero benefit.
Frontend is a proven no-op this cycle — built chunks are byte-identical to those already served — so a fleet node only changes binary + the two app-UI images + nginx.
Remaining to ship: operator go/no-go, then scripts/create-release.sh 1.7.120-alpha
(stops at the signing prompt — reads the master mnemonic interactively, operator-only),
then publish-release-assets.sh to gitea-vps2, then push tags. CHANGELOG.md already
carries curated v1.7.120-alpha notes (create-release.sh hard-fails without them).
The 5x lifecycle gate was NOT run.
Session Continuity
Last session: 2026-08-06 (resumed)
Stopped at: Session resumed 2026-08-06 via /gsd-resume-work. Tree clean, in sync with
gitea-ai @ 7bb09ffe. 13-14 COMPLETE (14/15), next 13-15 device-close — BLOCKED on four
operator browser checks (list in .planning/todos/pending/2026-08-06-open-operational-tasks.md,
which also carries the four non-phase node/infra tasks and the follow-on A/B/C proposal).
Awaiting operator choice between: (a) run the four checks and close 13-15/the phase,
(b) start follow-on Phase B (web-search setting derives the CSP, node-side), (c) take a
node/infra task (app-gate iframe login decision, Starting-vs-Unreachable, .228 frontend).
NOTE: .planning/HANDOFF.json + .planning/.continue-here.md are STALE (phase 09, 2026-08-02,
fully reconciled) and should not be read as live resume context.
Prior (13-12) stop note, retained for history: Completed 13-12-PLAN.md (D-10 untrusted-content boundary, G-B1/G-B2 cloud-egress screen, G-B3 read-only-loop rate limit + owner notices).
assistant:: tests incl. approval_nonce_binds_to_exact_action individually; dispatcher.rs
untouched; fc09d7a2's tools.rs/grants.rs/backends/mod.rs diffs confirmed rustfmt-only, no
behavior change). Task 2 (ToolConfirmModal.vue, contextBroker.ts, Chat.vue mount,
toolConfirm.test.ts) was already complete in fc09d7a2 — all 10 toolConfirm.test.ts cases pass,
pre-existing contextBroker/chatAiuiEmbed suites (28 tests) still green, vue-tsc clean, all
acceptance-criteria greps pass. fc09d7a2 stands as commit of record for both Task 1 and Task 2.
STOPPED at Task 3 (checkpoint:human-verify, gate=blocking) — on-device dialog verification on
archi-dev-box is required before 13-08-SUMMARY.md can be written. Resume: build+deploy per
Task 3's how-to-verify, then re-invoke the 13-08 executor with the operator's "approved" signal.
Resume file: None
Open on this thread (all recorded as broken windows, none blocking):
-
Window 15 CLOSED 2026-08-02 20:02 — f6b5245b's reconcile path proven on archi-dev-box by a controlled test: stale conf installed + container restarted (probe 200, genuinely re-exposed), daemon started, reconcile repaired it unaided at 20:02:19 with the expected warn line, probe 401, conf byte-identical to the known-good. Both halves now proven on hardware.
-
Windows 11/12: host-secret rotation on three fleet nodes sharing SSH host keys — detect-only so far; rotation is USER-GATED and deliberately not actioned.
-
Credential rotation DECIDED AGAINST 2026-08-02 (operator): no LND macaroon rotation, no Bitcoin RPC password rotation — no evidence of exploitation and the vulnerability is being closed rather than lived with. rotate-lnd-macaroon.sh stays as a tool, exercised in detect mode only, never run against a node. Do not re-litigate; see docs/security/BITCOIN-RPC-PROXY-EXPOSURE.md.
-
Dev-pair verification is archi-dev-box ONLY, by operator instruction 2026-08-02. Do not raise archy-x250-dev as a blocker again.