MalloryEstate Briefing
M·014Approved
← All briefings

Feature Waves

Wave 2.5 — Intel, Loops & Lifecycle

A deliberate way to dismiss clutter and retrieve what's hidden, plus a mic on loop item-add.

Dated 2026-06-12Programme Feature Waves

Situation

Completed digs accumulated forever with no way to clear them, while done loops silently vanished after ~36h (still in D1) with no way to recall them. This wave gives the user a deliberate dismiss and retrieve for both.

It also closes a modality gap: loop item-add was text-only in an otherwise voice-first app. The fix is a hybrid lifecycle — mirroring each entity's existing behaviour rather than unifying under one flag — since the *retrieve* half rhymes with, but stays earlier and simpler than, Wave 5's search.

Key decisions

Archive trigger

Hybrid: digs get a manual Dismiss (terminal states only); loops keep their existing ~36h auto-hide, now retrievable.

Archive surface

A separate full-screen app-menu view, sibling of the report viewer — not a tray segment, to keep the tray uncluttered.

Loop retrieval

Both Reopen (→ active) and Continue → (handoff) are available from the Archive.

Schema diverges from the roadmap guess

Only investigations gets new columns (archived, archived_at); loops need none — "archived" is expressed as a query (status='done' AND completed_at < now-36h), not stored state.

Item-add modality

Add a mic to loop item-add, reusing the composer's transcribe flow — no vocabulary changes to the existing "Follow up →"/"Continue →" verbs or the "Hand off to" toggle.

Architecture

Additive D1 columns on investigations plus new archive/restore/reopen endpoints, surfaced through a new full-screen ArchiveView.

migrations/008_investigation_archive.sql
Adds archived + archived_at to investigations, default 0 — additive and backward-compatible.
Worker archive/restore/reopen routes
POST /investigations/:id/archive|restore, POST /loops/:id/reopen, GET /investigations?archived=1, GET /loops?scope=archive — shaped like existing loop-mutation handlers.
ArchiveView.svelte (new)
Full-screen overlay, lazy-loaded on open; Dismissed digs + Past loops sections, each row with Restore/Reopen + Read the report→/Continue→.
TraySheet.svelte
Adds a quiet Dismiss control to terminal digs (optimistic removal, revert-on-failure) and a mic button beside loop item-add.
+page.svelte wiring
New archiveOpen state + app-menu item; new api.ts functions (archiveInvestigation, restoreInvestigation, reopenLoop, etc.).

Risks & guardrails

In-flight digs hidden by mistake

Dismiss is guarded to terminal states (done/failed); the endpoint 409/422s on a non-terminal dig with no mutation.

Stale tray after Archive action

Restore/Reopen optimistically remove from the Archive list, then refresh the relevant live store so the item reappears next time the tray opens.

Local preview can't verify full round-trip

The Access-gated API isn't reachable from local web preview, so dismiss→archive→restore and reopen round-trips are verified on deploy; Worker logic is covered independently by unit tests.

Delivery

Phase 1 — Worker backend

Migration 008; investigation archive db helpers + routes; loop reopen + archived-list db helpers + routes.

Phase 2 — Web client

api.ts archive functions; ArchiveView component; wire it + menu item into +page.svelte; Dig Dismiss action in the tray.

Phase 3 — Modality: item-add mic

Extract captureSpeech() in session.svelte.ts; add the mic to loop item-add.

Phase 4 — Rollout

Apply migration to remote D1, then deploy Worker and web — both held for Alex; migrate-before-deploy ordering called out explicitly.

Out of scope

Retention/purge of archived rowsAn `archived` flag on `threads` (Reopen + query cover it)Search over the archive (Wave 5's job; may later index this)Bulk dismiss / bulk restoreArchive for any entity other than digs and loops
spec · docs/superpowers/specs/2026-06-12-wave-2.5-intel-loops-lifecycle-design.md
plan · docs/superpowers/plans/2026-06-12-wave-2.5-intel-loops-lifecycle.md
Mallory · Estate briefing