350 lines
22 KiB
Markdown
350 lines
22 KiB
Markdown
# Warm-Hive PR3.5 — Memory-Trust Build Plan
|
||
|
||
> Synthesized from the 5 recon files in `docs/redesign-warm-hive/pr35-recon/` (01–05),
|
||
> all verified on branch `feature/warm-hive-pr3` @ `dac7b696`, 2026-06-16.
|
||
> This plan has two halves: **Part 1** = the `frame.source` projection (the keystone
|
||
> enabler), **Part 2** = the screen-19 Memory-Trust UI, built in phases on top of it.
|
||
>
|
||
> Repo root: `D:/Projects/waggle-os`. Substrate: `packages/hive-mind-core/src/mind/`.
|
||
> Server: `packages/server/src/local/routes/`. UI: `apps/web/src/`.
|
||
>
|
||
> **No-fabrication contract (inherited from PR3):** confidence, freshness, and trace-reason
|
||
> are the three places this PR could silently invent data. The plan gates each one off
|
||
> (PR3 streak pattern) wherever the substrate does not hold a real value. See §3 + §5.
|
||
|
||
---
|
||
|
||
## Part 1 — `frame.source` projection (the keystone enabler)
|
||
|
||
The ⬡ provenance pill on Chat + Workspace is blocked by one missing column in two read
|
||
paths. Recon 01 maps the FE-facing path (the `/context` route → `WorkspaceBriefing`); recon
|
||
02 maps the SSE step path. The DDL column already exists and is NOT NULL DEFAULT — **no
|
||
migration, no DDL change, no backfill.** This is a pure read-side projection.
|
||
|
||
### 1.1 The column (no change — context only)
|
||
|
||
`packages/hive-mind-core/src/mind/schema.ts:56-57` —
|
||
`source TEXT NOT NULL DEFAULT 'user_stated' CHECK (source IN ('user_stated','tool_verified','agent_inferred','import','system'))`.
|
||
Persisted rows only ever hold these **5** values (the TS `FrameSource` union at
|
||
`frames.ts:25` is wider — `personal|workspace|team_sync` are search-time mind labels that
|
||
fail the CHECK and never persist). The FE owns the label/icon map for the 5 values; the
|
||
route returns the raw string.
|
||
|
||
### 1.2 Workspace Briefing path — REQUIRED (the FE pill keystone)
|
||
|
||
**File A — `packages/server/src/local/routes/workspaces.ts`** (`GET /api/workspaces/:id/context`, handler @ `:364`)
|
||
|
||
Ordered edits:
|
||
|
||
1. **`:376`** — widen the `let recentMemories` local from
|
||
`Array<{ content: string; importance: string; date: string }>` →
|
||
`Array<{ content: string; importance: string; source: string; date: string }>`.
|
||
2. **`:377`** — widen the `let recentDecisions` local from
|
||
`Array<{ content: string; date: string }>` →
|
||
`Array<{ content: string; source: string; date: string }>`.
|
||
*(Skipping 1+2 makes the server `tsc` fail against the narrower locals — and `npm run build` does NOT typecheck the sidecar, so this only surfaces under the §1.4 server tsc.)*
|
||
3. **`:393-400`** — `recentMemories` SELECT: add `source` to the column list and to the
|
||
`as Array<{...}>` cast → `SELECT content, importance, source, created_at FROM memory_frames …`.
|
||
4. **`:402-406`** — `recentMemories` `.map()` projection: add `source: f.source,`.
|
||
5. **`:409-417`** — `recentDecisions` SELECT: add `source` to the column list and cast →
|
||
`SELECT content, source, created_at FROM memory_frames …`.
|
||
6. **`:419-429`** — `recentDecisions` `.map()` returned object: add `source: f.source,`.
|
||
|
||
(Exact before/after blocks are in recon 01 §2a/§2b — copy them verbatim.) Purely additive;
|
||
no existing consumer breaks.
|
||
|
||
**File B — `apps/web/src/lib/types.ts`** (interface `WorkspaceContext`, `:248-249`)
|
||
|
||
7. Widen both inline item shapes with an **optional** `source?`:
|
||
- `recentDecisions?: Array<{ content: string; source?: string; date: string }>;`
|
||
- `recentMemories?: Array<{ content: string; importance: string; source?: string; date: string }>;`
|
||
- Keep `source` optional so pre-PR3.5 sidecars still typecheck and the FE degrades to
|
||
"no pill" when absent.
|
||
|
||
**Consumer (no type change, render only) — `apps/web/src/components/os/WorkspaceBriefing.tsx`**
|
||
|
||
8. `recentMemories` rendered at `:186-197` (importance badge `:189-193`) and `recentDecisions`
|
||
at `:164-178`. Swap the bare mono date `<div>` for
|
||
`<ProvenanceLine source={m.source} when={m.date} onClick={…} />` **only when `m.source` is
|
||
present**; otherwise keep PR3's bare date `<div>` (the date-only fallback — never a
|
||
fabricated source). This is the same affordance PR3 already left hooked.
|
||
|
||
**DO NOT TOUCH — the parallel system-prompt builder.** `workspace-context.ts` /
|
||
`workspace-state.ts` (`buildWorkspaceState` → `WorkspaceNowBlock`) feeds the **system
|
||
prompt**, not the FE pill, and its `StateItem.source` is a *different* axis
|
||
(`memory|session|awareness`). Adding `frame.source` there is out of scope and would collide
|
||
on the `source` name (recon 01 §4). *(Note: recon 05 §7 names `workspace-context.ts:283-284`
|
||
as "the" projection gap — that is the system-prompt path; the FE pill keystone is the
|
||
`workspaces.ts` `/context` route in recon 01. They are different routes; for PR3.5 the FE
|
||
pill, do File A above, not `workspace-context.ts`.)*
|
||
|
||
### 1.3 SSE step path — DECISION: **project on `auto_recall` only, paired with the recallMemory widen** (recon 02)
|
||
|
||
Recon 02 verdict: **NEEDS-WIRING, not trivially projectable.** A streamed `step` carries
|
||
`{ content: string }` only; the agent loop exposes `onToolUse/onToolResult(name,input,result)`
|
||
with no frame/source; the real `source` is destroyed when `recallMemory()` flattens frames to
|
||
`string[]` text (`orchestrator.ts:453-457`).
|
||
|
||
**Project-or-defer decision:**
|
||
- **Blanket "source on every step" is WRONG by design** — generic steps (bash, drafting,
|
||
budget) have no provenance; stamping them is fabrication (PR3's refused move).
|
||
- **Only the memory-recall step (`auto_recall`) has genuine provenance.** Wiring it is
|
||
in-scope for PR3.5 **iff paired with the `recallMemory` return-shape widen**. If we want to
|
||
stay server-light this arc, **DEFER** the SSE step pill and keep PR3's "render the affordance,
|
||
never fabricated provenance" stance — the Chat ActivityStream already gates on
|
||
`s.provenance` presence, so nothing breaks.
|
||
|
||
**Recommended for PR3.5: do the `auto_recall` slice** (it is the honest, load-bearing one and
|
||
the same "frame.source 1-field projection" the S2 handoff named). The 5 edits / 4 files:
|
||
|
||
1. **`packages/agent/src/orchestrator.ts:453-457`** (load-bearing) — widen `recallMemory()`
|
||
return to carry per-snippet provenance, e.g. add
|
||
`recalledFrames?: Array<{ text: string; source: FrameSource; sourceUrl?: string; when?: string }>`
|
||
alongside the existing `recalled: string[]`. Frame objects with `.source` are already in
|
||
hand inside `recallMemory` — this is "stop flattening it", not a new query.
|
||
2. **`packages/server/src/local/routes/chat.ts:780-781`** — emit `source`/`provenance` on the
|
||
`auto_recall` step or its `tool_result` (`{ content, provenance?: { source, when } }` is
|
||
additive, backward-compatible).
|
||
3. **`apps/web/src/lib/types.ts:474-479`** — add optional `provenance?: { source: string; when?: string }`
|
||
to `StepContentBlock` (and tolerate it in `StreamEvent.data` handling, `:616-619`).
|
||
4. **`apps/web/src/hooks/useChat.ts:152`** — carry `data.provenance` onto the pushed step block.
|
||
5. **`apps/web/src/components/os/apps/chat-blocks/BlockRenderer.tsx:30-33`** — project
|
||
`s.provenance` into `ActivityStep` (the `ActivityStream`/`ProvenanceLine` path already
|
||
gates on presence; remove only the part of the omitted-provenance comment that no longer
|
||
holds). Leave all non-memory steps provenance-less by design.
|
||
|
||
### 1.4 Verification (Part 1)
|
||
|
||
```bash
|
||
# server route typecheck — REQUIRED; npm run build skips the sidecar (runs via tsx transpile-only)
|
||
npx tsc --noEmit --project packages/server/tsconfig.json
|
||
# agent (only if §1.3 done — recallMemory widen)
|
||
npx tsc --noEmit --project packages/agent/tsconfig.json
|
||
# FE typecheck — use the app tsconfig directly (the workspace alias is a silent no-op)
|
||
npx tsc --noEmit -p apps/web/tsconfig.app.json
|
||
npm run test -- --run # FE unit + touched server suites
|
||
npm run lint
|
||
```
|
||
Live check: open a workspace with seeded memories → Chat + Workspace Overview render the ⬡
|
||
pill on rows that have a `source`; rows without a source show the bare date (no fabricated
|
||
pill). Console: 0 errors.
|
||
|
||
---
|
||
|
||
## Part 2 — Memory-Trust (screen 19), phased
|
||
|
||
Target screen: `docs/design_handoff_waggle_app/design-files/screens/memory-trust.html`
|
||
(authoritative mock, 1:1 token match to PR3's warm tokens per recon 04 §8 — no remapping).
|
||
Two view modes behind a segmented control: **A "Manage memory"** (default) and **B "Why did
|
||
you do that?"**. The standalone host is `MemoryCenterApp.tsx` (screen 19 extends/replaces it);
|
||
the reusable core `memory/MemoryCenterTab.tsx` is shared by the Workspace Memory tab — change
|
||
once, both update (recon 03).
|
||
|
||
> **Reuse, don't rebuild:** `ConfidenceBadge`, `EvidenceChip`, `DetailDrawer`, `EvidencePanel`
|
||
> already exist in `components/ui/` (commit `afe96355`, pre-PR3) and ship today via Memory
|
||
> Center. The new warm atoms are only the 4 listed in §4.
|
||
|
||
### Phase 0 — Primitives (new warm atoms + token decision)
|
||
|
||
**Files to create** (`apps/web/src/components/os/warm/`, export from `warm/index.ts:7-20`):
|
||
- `ConfidenceRing.tsx` — the §5a 38px ring (see §4).
|
||
- `ConfidenceBadge` decision: the existing `ui/confidence-badge.tsx` uses the Hive DS
|
||
`--sem-*` family; the warm screen wants `--healthy/--attention/--risk`. **Token-family
|
||
decision (founder call, see §5):** align new Memory-Trust confidence atoms to the **warm
|
||
`--sem-*`→band** mapping the screen 19 mock uses (green ≥85 / honey ≥60 / terracotta <60),
|
||
OR reuse `ui/ConfidenceBadge` if its `--sem-*` bands render acceptably. Default
|
||
recommendation: build `ConfidenceRing` against warm tokens (matches the mock exactly),
|
||
reuse `ui/ConfidenceBadge` where a pill (not a ring) is wanted.
|
||
- `EvidenceChip` for the trace: reuse `ui/evidence-chip.tsx` (recon 03). Only build a thin
|
||
`TraceEvidenceChip` wrapper if the §6b `.ev` chip needs the multi-segment
|
||
`confidence X% · source · when · still fresh` format.
|
||
- `DetailDrawer`: reuse `ui/detail-drawer.tsx` (recon 03) for the memory-detail open.
|
||
|
||
**Files to modify:** `ProvenanceLine.tsx` — extend to optionally render the §5b 3-segment
|
||
form `⬡ <id> · source: <src> · ● <freshness>` (add a `source:`-prefix variant + a `●`
|
||
freshness segment colored healthy/attention). Today it renders `⬡ source · when` only.
|
||
|
||
**Tokens/primitives reused:** all `--honey/--healthy/--attention/--risk/--intel` + washes +
|
||
`--r-lg 18px`/`--r-xl 26px` + JetBrains Mono/Hanken already defined in both themes
|
||
(`index.css:162-168` dark / `:298-304` light). `HexAvatar`, `SectionLabel`, `DotLive`,
|
||
`RunChip`/chip patterns already exist.
|
||
|
||
**Data:** none (pure presentational atoms).
|
||
|
||
### Phase A — Header / segmented control + editorial hero + stat bar
|
||
|
||
**Files to create/modify:**
|
||
- New `MemoryTrustApp.tsx` (or extend `MemoryCenterApp.tsx`) hosting the §1 sticky `.controls`
|
||
bar: eyebrow `Memory Trust · view`, 2-button segmented switch (`Manage memory` default-on
|
||
honey-fill `#1a1407` ink | `Why did you do that?`), swapping `.vlabel`, theme toggle.
|
||
- §2 editorial hero per view (honey eyebrow + 28px/650 H1 with honey non-italic `<em>` accent
|
||
+ 64ch body with bold `--text-2` spans). Verbatim copy in recon 04 §2.
|
||
- §3 stat bar (View A): 4 cards `repeat(4,1fr)`→2-col @820px.
|
||
|
||
**Primitives/tokens:** `SectionLabel` for eyebrows; honey-fill segment = `.seg button.on`
|
||
treatment (`background:var(--honey); color:#1a1407`); warn cards use the
|
||
`--attention`/`color-mix` border per recon 04 §3.
|
||
|
||
**Data — REAL vs route-needed:**
|
||
- Stat #1 "Memories in this hive" (`142`) — **REAL**, from `GET /api/memory/stats` (counts
|
||
only, mind-isolation honored).
|
||
- Stat #2 "High confidence & fresh" (`128`) — **DERIVABLE/PARTIAL**: confidence is sparse
|
||
(harvest-only), freshness is derivable from `created_at`. **If confidence is absent for the
|
||
mind, gate this card off** (show "—" or hide), do not invent a count. See §3.
|
||
- Stat #3 "Stale · worth a review" (`9`) — **DERIVABLE** from `created_at` via
|
||
`computeTemporalScore` (FE compute or thin route).
|
||
- Stat #4 "Awaiting your confirm" (`3`) — **needs route**: `GET /api/memory?status=unreviewed`
|
||
(filter already works, `memory-center.ts:198`) — but nothing *writes* `unreviewed` today, so
|
||
the count may legitimately be 0. Wire to the real query; do not seed a fake number.
|
||
|
||
### Phase B — Search + filters (View A toolbar)
|
||
|
||
**Files to modify:** the §4 `.toolbar` inside `MemoryTrustApp` — search input (placeholder
|
||
`Search what Waggle knows… or ask it to forget something`) + 4 filter chips (`All` on /
|
||
`Stale` / `Needs confirm` / `Forgotten`).
|
||
|
||
**Primitives/tokens:** active chip = `--honey-wash` fill + `--honey-line` border (recon 04 §4);
|
||
reuse warm chip pattern.
|
||
|
||
**Data — REAL vs route-needed:**
|
||
- Search → `GET /api/memory?mind&q&kind&status&minConfidence&limit` (`memory-center.ts:167`) —
|
||
**REAL**.
|
||
- `Stale` filter → **DERIVABLE** client-side over returned `created_at`.
|
||
- `Needs confirm` filter → `GET /api/memory?status=unreviewed` — **REAL query** (may return 0).
|
||
- `Forgotten` filter → **no tombstone exists** (forget is a hard delete, `frames.ts:321`).
|
||
**Gate this chip off** or relabel — there is no "forgotten" list to show. See §3.
|
||
|
||
### Phase C — Memory rows (confidence ring + provenance + forget/correct/confirm/stale)
|
||
|
||
**Files to create/modify:** the §5 `.mem` row component (3-col `[conf ring] [body] [actions]`),
|
||
rendered into `.mems` grid. Reuse the `memory/MemoryCenterTab.tsx` + `MemoryCard.tsx` pattern
|
||
(already consumes `DetailDrawer`/`ConfidenceBadge`/`EvidencePanel`); add the warm row treatment.
|
||
|
||
**Primitives/tokens:** new `ConfidenceRing` (§4); extended `ProvenanceLine` (3-segment §5b);
|
||
corrected banner = `--healthy-wash`; stale banner = `--honey-wash`+`--honey-line`; disputed =
|
||
`--risk` border + strikethrough; danger-forget hover = `--risk` (recon 04 §5).
|
||
|
||
**Data — REAL vs route-needed:**
|
||
- Row content / id / source → **REAL** (from `/api/memory` `Memory` shape).
|
||
- **Forget** button → `DELETE /api/memory/:id?mind=…` — **REAL, no new backend** (hard delete +
|
||
audit event). Row animates out then removed.
|
||
- **Correct / edit** button → `PATCH /api/memory/:id` (content + reclassify) — **REAL, no new
|
||
backend**.
|
||
- **Confidence ring** → `Memory.confidence`, **only present on harvested frames**. **Hide the
|
||
ring (or show a neutral "—" state) when `confidence` is undefined** — never default a number.
|
||
See §3.
|
||
- **Freshness `●`** → **DERIVABLE** from `created_at` (`computeTemporalScore`, 7-day boost /
|
||
30-day half-life). Present as honest age ("aging — last seen 6w ago"), never a stored %.
|
||
- **Stale banner / "Still true?"** → derivable trigger; **Confirm** action → **MUST-BUILD
|
||
route** `POST /api/memory/:id/confirm` (set `metadata.status='active'`, mirroring
|
||
`/archive` at `memory-center.ts:355`). Cheap; the `MemoryStatus` rails exist.
|
||
|
||
### Phase D — "Why did you do that?" trace (View B)
|
||
|
||
**Files to create/modify:** the §6 `.trace` card — `HexAvatar` header (`trace #a1f9`), 4-node
|
||
connector chain (Goal→Recalled 3→Cross-checked→Acted; dots intel/honey/honey/healthy; evidence
|
||
chip `confidence 94% · source: chat · Tue · still fresh`), 3-button footer (Looks right / That
|
||
memory is wrong → correct it / Forget #M-204 & redo). Shared trust-principle footnote + green
|
||
slide-up toast on both views.
|
||
|
||
**Primitives/tokens:** `HexAvatar`, `DotLive`, reused `EvidenceChip`; connector line per §6b;
|
||
footer go-button honey-fill / ghost / danger per §6c.
|
||
|
||
**Data — REAL vs route-needed (the honest hard part):**
|
||
- Trace store is **rich and populated for chat** (`execution_traces` + `TraceRecorder` per
|
||
turn, `chat.ts:1277-1424`): reasoning[], toolCalls[], outcome, cost, tokens.
|
||
- **GAP 1 — chat traces aren't addressable by the agent-traces route.** `GET /api/agents/:id/traces`
|
||
(`agents.ts:469`) filters by the `agent:{id}` tag, but chat `start()` does NOT pass
|
||
`tags:['agent:…']` (`chat.ts:1279-1285`). Fix = either add the `agent:` tag at chat
|
||
`start()`, OR add a thin `GET /api/sessions/:id/traces` reading
|
||
`traceStore.queryParsed({ sessionId })` (store already supports it, `execution-traces.ts:328`).
|
||
- **GAP 2 — no frame↔trace backlink.** Nothing links a `memory_frame` to the
|
||
`execution_trace` that produced it (no `trace_id`). So **per-frame "why is THIS memory here?"
|
||
is MUST-BUILD** (add `trace_id` to frame metadata at write time + a `GET /api/memory/:id/trace`
|
||
resolver). For PR3.5 the **honest, cheap win is a session/turn-scoped trace view** (the real
|
||
reasoning + tool calls), NOT a per-frame reason. **Do NOT synthesize a "reason" string for a
|
||
frame with no linked trace.** If neither route lands this arc, View B renders against a real
|
||
recent session trace or is gated behind "no trace yet" empty state — never fabricated.
|
||
|
||
### Phase verification (each phase)
|
||
Run the §1.4 gate after each phase; live-smoke the screen in dark + light with 0 console
|
||
errors before moving on (matches PR3's shipping bar).
|
||
|
||
---
|
||
|
||
## 3. Honest data gaps (recon 05)
|
||
|
||
| Feature | REAL / DERIVABLE / MUST-BUILD | Plan |
|
||
|---|---|---|
|
||
| **source** (provenance class) | REAL (`memory_frames.source`) | Project per Part 1; FE owns the 5-value label map. |
|
||
| **forget** (delete) | REAL (`DELETE /api/memory/:id`, hard delete + audit) | Wire button straight to it. No backend. |
|
||
| **correct** (edit) | REAL (`PATCH /api/memory/:id`) | Wire edit/correct to it. No backend. |
|
||
| **freshness / staleness** | DERIVABLE (`computeTemporalScore` over `created_at`, 7d boost/30d half-life) | FE compute or thin helper. **Present as honest age, never a stored "%".** |
|
||
| **confidence** | PARTIAL (metadata blob; **harvest-only**, `undefined` for curated/agent/quick-capture frames) | **Show ONLY when present; hide the ring/badge when `undefined`. NEVER default a number** (PR3 streak-gate pattern). Stat #2 gated off if absent. |
|
||
| **confirm / needs-confirm / verified** | MUST-BUILD (no per-frame confirm lifecycle; `unreviewed` never written) | Add cheap `POST /api/memory/:id/confirm` (set `metadata.status`), mirror `/archive`. Queue = `?status=unreviewed`. **Do NOT show "verified ✓" unless `source==='tool_verified'` or status explicitly set.** |
|
||
| **per-frame "why?" trace** | MUST-BUILD backlink (no `trace_id` on frames); session/turn trace is DERIVABLE | Ship session/turn-scoped View B from real traces (add `agent:` tag or `/api/sessions/:id/traces`). **Never synthesize a reason for an unlinked frame.** |
|
||
| **"Forgotten" filter** | NO DATA (hard delete = no tombstone) | **Gate the chip off / relabel** — there is no forgotten list. |
|
||
|
||
**Fabrication-risk flags (gate off, do not invent — PR3 streak precedent):**
|
||
1. **Confidence** when undefined → hide ring, don't default.
|
||
2. **Freshness** → age, never a stored decay %.
|
||
3. **Per-frame trace reason** → only when a real linked trace exists.
|
||
4. **"Forgotten" list** → no tombstone; gate off.
|
||
5. **Stat-card numbers** → drive from the real query; a real 0 is honest, a fake `3`/`9`/`128` is not.
|
||
|
||
---
|
||
|
||
## 4. New primitives to build (recon 03 confirmed: 3 already exist — REUSE)
|
||
|
||
**Already exist in `components/ui/` (pre-PR3, commit `afe96355`) — do NOT rebuild:**
|
||
`ConfidenceBadge`, `EvidenceChip`, `DetailDrawer`, `EvidencePanel`. The handoff's claim they'd
|
||
be in `os/warm/` was a location error — they ship today via Memory Center.
|
||
|
||
**Genuinely new warm atoms for screen 19** (one-line spec each):
|
||
|
||
- **`ConfidenceRing`** — 38px circular ring; number + 2px border both colored by band (≥85
|
||
`--healthy` / ≥60 `--attention` / <60 `--risk`); `CONF` mono caption beneath; **renders the
|
||
"no value" neutral state when `confidence` is undefined** (no fabricated number).
|
||
- **`ProvenanceLine` (extend, not new)** — add the §5b 3-segment form
|
||
`⬡ <id> · source: <src> · ● <freshness>` (`source:`-prefix variant + `●` freshness segment
|
||
colored healthy/attention); keep the existing `⬡ source · when` form + `onClick` → button.
|
||
- **`TraceEvidenceChip`** (thin wrapper over `ui/EvidenceChip`) — multi-segment trace chip
|
||
`confidence X% · source · when · still fresh` in `--surface`/`--line-soft`, `.src` refs mono
|
||
`--intel`; only if the plain `EvidenceChip` can't render the multi-segment string directly.
|
||
- **`DetailDrawer` (reuse)** — already exists; opened from a clickable memory row for the full
|
||
memory detail (confidence/source/evidence/edit). No new build.
|
||
|
||
*(Net new code: `ConfidenceRing` + the `ProvenanceLine` extension; optional `TraceEvidenceChip`.)*
|
||
|
||
---
|
||
|
||
## 5. Risks & open questions for the founder
|
||
|
||
1. **SSE step pill — do it now (auto_recall slice) or defer?** Recon 02: in-scope only if
|
||
paired with the `recallMemory()` return-shape widen (`orchestrator.ts:453-457`). If we want
|
||
PR3.5 frontend-light, defer and keep PR3's affordance-only stance. **Recommend: do the
|
||
`auto_recall` slice** (honest, load-bearing). Founder call on scope/budget.
|
||
|
||
2. **Token-family decision (recon 03 §1b):** warm `--intel` (provenance) vs Hive DS `--sem-*`
|
||
(confidence bands) currently coexist. Screen 19's confidence rings use warm
|
||
`--healthy/--attention/--risk`. Confirm: build `ConfidenceRing` against warm tokens and let
|
||
`ui/ConfidenceBadge` keep `--sem-*`, or unify? Default: warm tokens for the ring (matches
|
||
the mock 1:1).
|
||
|
||
3. **Confirm route + status writer.** `POST /api/memory/:id/confirm` is cheap, but nothing
|
||
writes `unreviewed` today, so the "Awaiting your confirm" queue may legitimately be empty.
|
||
Is that acceptable for launch (real-but-empty), or do we also wire the harvest-commit path
|
||
to stamp `unreviewed` (larger)?
|
||
|
||
4. **Per-frame "why?" backlink.** True per-memory trace needs a `trace_id` on frame metadata
|
||
at write time + a resolver (MUST-BUILD). For PR3.5, accept a **session/turn-scoped** View B
|
||
(real traces, not per-frame)? Or invest in the backlink this arc?
|
||
|
||
5. **"Forgotten" filter has no data** (hard delete, no tombstone). Gate the chip off, relabel,
|
||
or add a soft-delete tombstone (scope creep)? Recommend: gate off for now.
|
||
|
||
6. **Two-mind scope for screen 19.** `MemoryCenterApp` is two-mind (personal/workspace) and
|
||
the Workspace Memory tab shares `MemoryCenterTab`. Does screen 19 replace `MemoryCenterApp`
|
||
wholesale, or layer the Trust view as a new view alongside the existing 7
|
||
(`memories·timeline·graph·harvest·weaver·wiki·evolution`)? Affects blast radius.
|