Files
waggle-os/docs/ux-refactor/deltas/open-questions.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

54 KiB
Raw Permalink Blame History

Open Questions — UX Refactor (Founder Ratification)

Source: PRD §23 (docs/Waggle_OS_UX_Refactor_Master_Handoff_Package/Waggle_OS_UX_Refactor_PRD.md:1414-1424)

  • the §9 "Open questions" sections of all 22 gap cards (docs/ux-refactor/gap-cards/S00..S21). Every recommendation is kept consistent with the locked direction: in-place incremental refactor of apps/web + targeted backend extensions, full-stack (net-new/extended APIs where PRD §16 has no route yet), local-first default. Mockups are directional (PRD §24); PRD acceptance criteria win.

How to use: each question has (a) why it matters, (b) options + tradeoffs, (c) a RECOMMENDED answer for founder ratification, (d) the phase it blocks if unresolved. Questions are grouped: §A = the 8 PRD §23 questions; §B = cross-cutting decisions surfaced by the gap cards that block ≥2 screens; §C = screen-local questions that block a single screen. Critical (Phase 12 blocking) items are flagged [BLOCKS P1] / [BLOCKS P2].


Founder Ratifications — 2026-06-09

The spine (Phase 0/1) blockers are RATIFIED as recommended (founder, 2026-06-09). Phase 0 is unblocked; these are now locked decisions alongside the execution-model + full-stack scope locks:

  • B1 Shell topology → in-place dock reframe; keep windowed AppId nav; group the dock into Work / Intelligence / Extend / Team zones. No react-router.
  • A1 Workspace Desktop → fixed widget layout v1.
  • A2 Home Cockpit → personal-only v1 (team strip later, behind RBAC).
  • B4 /api/* → alias PRD vocabulary onto existing routes (command / automations / connector-revoke); do not rename.
  • B8 Identity → onboarding writes profile and seeds the identity table.

Founder Ratifications — Phase 2 gate (2026-06-09 S2)

The Phase-2 blockers are RATIFIED as recommended (founder, 2026-06-09), except C33 which is held for discussion (see note below). Locked Phase-2 decisions:

  • A6 Artifact storage → per-workspace artifacts.json index over the existing StorageProvider; artifact = explicit produced output (not every ingested input). No .mind migration.

  • A8 Memory retention → soft-status in metadata (Archive = reversible; Deprecate = existing importance); Delete = hard delete behind a scope-and-consequence confirmation (PRD J20). ≤1 additive migration.

  • B2 Confidence → cheap heuristic at preview (source-trust × adapter-type × dedup), persisted in metadata only if it becomes a queryable filter; LLM scoring reserved for the standing J08 queue.

  • B6 MemoryKind → PRD §15.2 canonical in @waggle/shared; pure harvest + display-category mapping helpers. Drop FE event/insight drift.

  • A3 Memory graph tab → ship in v1 (substrate already renders).

  • C33 Import↔Review commit split → RESOLVED to the middle path (founder, 2026-06-09 S2, after discussion). Commit-as-unreviewed, non-blocking review: onboarding Import commits immediately (memory feels alive on first run), but frames land with status:'unreviewed' + the B2 confidence score; Review is a non-blocking curation surface (Memory Center "needs review" filter + the standing J08 queue), NOT a blocking onboarding step. Reads PRD "nothing imports without review/approval" (646/1207) as nothing is trusted/surfaced until reviewed, not nothing is written. Rationale: importing one's own memories is additive + reversible (A8 archive/delete), so a blocking first-run gate would be friction in the wrong place (founder principle: friction reserved for irreversible/destructive actions). Reuses A8 soft-status

    • B2 confidence — no extra migration. Supersedes the original §C C33 "blocking split" recommendation.

Founder Ratifications — Phase 3 gate (2026-06-10)

The Phase-3 (Intelligence) items are RATIFIED as recommended (founder, 2026-06-10). Locked:

  • B3 Agent entity → real Agent object in {dataDir}/agents.json referencing personaId; persona = behavioral template field. successRate/lastRun derived at read from execution_traces. No .mind migration (M3 not shipped).
  • C24 Automation triggers → schedule-only v1 (cron cadence); Event trigger deferred (no event→automation dispatch substrate).
  • C26 Builder test-run → NET-NEW no-persist dry-run route (POST /api/automations/test); do NOT reuse cron/:id/trigger (executes + auto-enables).
  • C13 Skill Builder publishes create-to-local (POST /api/skills/create); marketplace publish lives in S06/S21.
  • C14 Skill inputs/outputs → body markdown v1; no SkillFrontmatter extension.
  • C22 Agent Center tabs = All/Personal/Workspace/Team/Autonomous/Archive; Templates = side affordance.
  • C23 Agent /run → one-shot fleet-spawn into a chosen workspace (picker if multiple workspaceIds); persistent always-running agents deferred.
  • C25 Automation condition step → advisory jobConfig.condition string, no evaluation engine v1.
  • C27 Analytics tiles → keep success-rate (from cron_execution_history); drop "hours saved" or label it an explicit heuristic estimate.
  • C36 Skill scope vocabulary → PRD organization (align §15.2 Scope union).
  • C37 Skill test-run fidelity → preview-only (injected-prompt + parsed metadata) v1; live LLM dry-run deferred.

Founder Ratifications — Phase 4 gate (2026-06-10)

The Phase-4 (Extend) items are RATIFIED as recommended (founder, 2026-06-10). Locked:

  • A4 Real-where-substrate-exists, catalog-for-the-rest: connectors connect + health-probe + lastSyncAt stamp (background data re-pull deferred); MCPs install/start/stop/test via the existing marketplace installer + stdio runtime; static catalog renders honest "available / not installed" states — never fake entries (PRD §22.2).
  • A5 Marketplace → federate-at-read over the six local domains; no marketplace.db migration; remote registry / public marketplace deferred (PRD §4.4 + §22).
  • B5 Tier vocabulary → document the mapping; all new gates route through @waggle/shared tiers.ts (TierCapabilities); MCP Hub + Marketplace install gated PRO+.
  • B7 ExtensionTypeskill | agent | connector | mcp | model | template (drop external_tool; external tools surface via connectors/MCPs). Defined once in @waggle/shared.
  • C15 / M2 install-audit critical CHECK → ship the additive migration (live sighting: marketplace.ts:228 writes critical, silently rejected by the DDL CHECK today).
  • C16 Connector "sync now" v1 = re-probe health + stamp lastSyncAt.
  • C17 revoke purges OAuth tokens + writes the stronger audit entry (PRD §17.3); disconnect stays the lighter alias.
  • C18 One shared GET /api/extend/audit?type= serving connectors + MCPs + marketplace.
  • C19 MCP scope = single-workspaceId config v1 (matches stdio runtime); N:N deferred.
  • C20 "Remote Registry" tab deferred (runtime is stdio-only); v1 points at the static catalog.
  • C21 MCP test = live spawn-and-isHealthy()/tools/list round-trip where cheap; static manifest validation fallback.
  • Foundational task (coverage-check C4): populate mcpRuntime at boot from persisted config (local/index.ts registers none today) — explicit Phase-4 work item gating all MCP routes.

Remaining pending: A7 (RBAC — ratify before S10/Phase 5) + Phase-5/6 screen-local items.

§A — PRD §23 Open Questions (the canonical 8)

A1. Widget customization in Workspace Desktop — fixed layout or true customization in v1?

(PRD §23 Q1, line 1416; gap card S02 §9 Q1.)

  • (a) Why it matters: Determines whether S02 reuses the maximized AppWindow + fixed widget layout (cheap, in-place) or builds a draggable/resizable grid (parallel layout system, large blast radius). PRD §12.2 already says "configurable widgets in later phase; fixed default layout in initial release".
  • (b) Options:
    1. Fixed layout v1 — one default widget arrangement; reuse window manager. Lowest cost, ships Phase 1.
    2. Customizable grid v1 — drag/resize/persisted layout. New layout engine, persistence, much larger.
    3. Fixed + per-tab presets — fixed canvas but a couple of named presets. Middle cost.
  • (c) RECOMMENDED: (a) Fixed layout v1. PRD §12.2 self-answers this; customization is explicitly a later phase. Rationale: keeps Workspace Desktop a maximized window in the existing OS, zero parallel layout system.
  • (d) Blocks: Phase 1 (Workspace Desktop, S02). [BLOCKS P1] — but the PRD text already resolves it, so this is a confirm-not-debate.

A2. Home Cockpit scope — personal-only, or team/global views too?

(PRD §23 Q2, line 1417; gap card S01 §9 Q3, Q5.)

  • (a) Why it matters: Decides whether the briefing reads cross-workspace personal state only, or also team/shared rows. S01 §9 Q3 flags that reading the user's own workspaces server-side is now safe (same-user), while team/shared rows must still gate through approvalGrantStore/RBAC.
  • (b) Options:
    1. Personal-only v1 — briefing aggregates the user's own workspaces; team rows deferred to Phase 5.
    2. Personal + team summary v1 — adds a shared-activity strip (needs RBAC + Team substrate live).
    3. Toggle (personal/team) v1 — most flexible, most work; team substrate not ready until S10.
  • (c) RECOMMENDED: (a) Personal-only v1, with the briefing builder written so a team summary can be appended later behind the existing RBAC gate. Rationale: Team Workspace (S10) is a Phase-5 screen; Home must ship in Phase 1 without it. Local-first + own-data read is the safe boundary.
  • (d) Blocks: Phase 1 (Home Cockpit, S01). [BLOCKS P1].

A3. Memory Center graph view — v1 or later?

(PRD §23 Q3, line 1418; gap card S04 §9 / line 232.)

  • (a) Why it matters: Whether the "Graph" tab ships in the first Memory Center cut.
  • (b) Options:
    1. Ship graph in v1 — the knowledge_entities/knowledge_relations substrate + a graph render already work (S04 line 232: "Graph already works, so keep").
    2. Defer graph — tab hidden until a later polish pass.
  • (c) RECOMMENDED: (a) Ship in v1. Rationale: the substrate exists and S04 already confirms it renders; deferring would be removing working capability for no gain.
  • (d) Blocks: Phase 2 (Memory Center, S04). [BLOCKS P2] (scoping-only; default = keep).

A4. Which connectors/MCPs are real in v1 vs seeded/mock catalog?

(PRD §23 Q4, line 1419; gap cards S06 §9 Q3, S07 §9 Q1, S08 §9 Q4Q5, S14 §9 Q1, S15 §9 Q3, S21 §9 Q2.)

  • (a) Why it matters: Touches six screens. Determines the empty/syncing states of the Marketplace, Connector Hub, MCP Hub, Tool Discovery and Memory-Import surfaces, and whether onboarding can pull data in-flow. The connector registry has ~31 real entries; the MCP catalog (@waggle/shared mcp-catalog.ts) is static; MCP runtime is stdio-only (mcp-runtime.ts:108-115) and currently never populated (local/index.ts:911).
  • (b) Options:
    1. Real-where-the-substrate-exists, catalog-for-the-rest — OAuth connectors that already have SDK entries connect for real (health-probe + timestamp, no background data-sync — S07 §9 Q1); MCPs install via the existing marketplace installer (installer.ts:580 writes .mcp.json); everything else renders from the static catalog with honest "available / not installed" states.
    2. All-mock catalog v1 — nothing actually connects; fastest UI, but violates PRD §22.2 ("no major screen depends only on mocked data when backend support exists").
    3. All-real v1 — build connector background-sync + remote MCP transport now; out of scope per PRD §4.4.
  • (c) RECOMMENDED: (1) Real-where-it-exists, catalog-for-the-rest. Connectors: connect + health probe + lastSyncAt stamp (defer true data re-pull). MCPs: install/start/stop/test against the static catalog via the existing installer + stdio runtime; defer "Remote Registry" transport. Marketplace/Tool Discovery: render the live registry, never invent fake entries. Rationale: honors PRD §22.2 and the local-first default while staying in-place.
  • (d) Blocks: Phase 4 (S07/S08/S21) and the onboarding Phase 2 import flow (S14/S15). Not P1.

A5. Marketplace — local catalog vs remote registry initially?

(PRD §23 Q5, line 1420; gap card S21 §9 Q2, S08 §9 Q4.)

  • (a) Why it matters: Whether S21 federates the existing local domains (marketplace.db + connectors + templates + personas + models) client-side, or invests in widening marketplace.db/InstallationType to natively catalog all six extension kinds.
  • (b) Options:
    1. Federate-at-read (local-first) — S21 composes the six categories from existing domains; no DB change; "Remote Registry" is a later tab. (S21 §9 Q2 recommendation.)
    2. Native unified catalog table — widen marketplace.db for publish/install/version parity across all six kinds. Enables update-tracking but is a real schema investment; conflicts with PRD §22 "postpone public marketplace".
  • (c) RECOMMENDED: (1) Federate-at-read, local catalog first. Remote registry / public marketplace billing stays out per PRD §4.4 + §22. Rationale: matches local-first + in-place; no marketplace.db migration.
  • (d) Blocks: Phase 4 (Marketplace, S21). Not P1/P2.

A6. Artifact storage — workspace filesystem, virtual store, or external references first?

(PRD §23 Q6, line 1421; gap card S05 §9 Q1, Q2.)

  • (a) Why it matters: Artifacts have no backing entity today (the single largest entity gap, S10 line 226). PATCH/relations/status/tags require a stable id + an index. The file registry mixes ingested inputs with produced outputs, so a kind/status classification rule is also needed.
  • (b) Options:
    1. Per-workspace artifacts.json index over the existing workspace FS/virtual store — mirrors documents.json; assigns stable ids, holds status/tags/relations; reuses the StorageProvider (virtual | local | team) already in the repo. (S05 §9 Q1.)
    2. Composite synthetic id (workspaceId:store:name), no index — cheapest, but can't persist status/tags/relations (PATCH becomes impossible).
    3. External references only — point at files elsewhere; defers the entity but breaks "artifacts are first-class outcomes" (PRD §6.4).
  • (c) RECOMMENDED: (1) artifacts.json index over the existing workspace storage, with a classification rule: an artifact is an explicit produced output (generated doc/deck/sheet/etc. or user-promoted file), not every ingested input. Rationale: gives PATCH/relations a home with no .mind migration, reuses the StorageProvider, keeps local-first.
  • (d) Blocks: Phase 2 (Artifact Center, S05); also gates artifact-sharing in S10. [BLOCKS P2].

A7. Minimum viable RBAC for team mode?

(PRD §23 Q7, line 1422; gap card S10 §9 Q1 (blocking), Q2.)

  • (a) Why it matters: Three role models disagree: PRD §17.2 (Owner/Admin/Contributor/Viewer), blueprint (+Member +Guest), and the live teams.db CHECK (owner/admin/member/viewer, team.ts:21). Picking wrong forces a DB CHECK migration + RBAC-logic rewrite. There is also a real bug: PUT …/members/:userId is owner-only (team.ts:624) while PATCH on the same path is owner/admin (team.ts:649).
  • (b) Options:
    1. Keep the live 4-role union (owner/admin/member/viewer) — map PRD "Contributor" → "Member", defer "Guest". No DB migration, no RBAC rewrite. (S10 §9 Q1 recommendation.)
    2. Adopt PRD §17.2 four roles literally — rename membercontributor in the DB CHECK + all enforcement (migration + grep-everywhere).
    3. Adopt blueprint six roles (+Guest) — new deny-by-default capability rules; largest scope.
  • (c) RECOMMENDED: (1) Keep the live union; Contributor==Member; defer Guest. Also align the PUT/PATCH gate to owner+admin (PRD uses PATCH; pick the broader gate consistently). Rationale: in-place, zero migration, fixes a real inconsistency.
  • (d) Blocks: Phase 5 (Team Workspace, S10) — the TeamRole type + all member-management UI. Not P1/P2, but must be ratified before S10 coding starts (S10 §6: "decision needed before coding").

A8. Memory retention / delete / tombstone behavior?

(PRD §23 Q8, line 1423; gap cards S04 §9 Q3, S16 §9 Q2.)

  • (a) Why it matters: PRD §14.4 distinguishes Deprecated / Archived / Deleted-tombstoned, but memory_frames has only importance:'deprecated' today and no status/tombstone column; delete is a hard FrameStore.delete. Determines whether an additive .mind migration is required and what "archive" vs "delete" mean to the user.
  • (b) Options:
    1. Soft-status via metadata JSON, hard-delete on Delete — store {status: active|archived| deprecated} in the existing metadata TEXT (idempotent ADD COLUMN pattern at db.ts:122 if a queryable column is needed); Delete = hard FrameStore.delete. Archive = reversible status.
    2. Full tombstone model — Delete writes a tombstone row (retained, hidden, syncable) for audit/undo. Heavier; needed only if team-sync conflict-resolution requires it.
    3. No status, delete-only — simplest, but loses the Archived/Deprecated states PRD §14.4 requires.
  • (c) RECOMMENDED: (1) Soft-status in metadata (Archive = reversible status, Deprecate = existing importance), Delete = hard delete with a scope-and-consequence confirmation (PRD J20). Promote status to a real column only if it becomes a primary filter axis. Defer full tombstones to the team-sync phase. Rationale: local-first, one additive migration at most, satisfies §14.4 states.
  • (d) Blocks: Phase 2 (Memory Center, S04) — and shares the confidence/metadata migration decision with the onboarding Memory Review (S16, see B2). [BLOCKS P2].

§B — Cross-cutting decisions (block ≥2 screens; not in PRD §23 but surfaced by gap cards)

B1. Shell topology — keep the bottom-dock OS, or migrate to a left-rail / route-based shell?

(Gap cards S00 §9 Q1Q2, Q5; S01 §9 Q4; S11 §9 Q5/Q7; S20 §9 Q7.)

  • (a) Why it matters: This is the Phase-0 IA freeze. The live shell is a single-route windowed OS with a bottom Dock.tsx; blueprint/mocks show a left navigation + /home,/workspaces,… route groups. Every later screen's navigation/AppId/dock placement depends on this. Deep-linking + browser back-button are the only things real routes buy.
  • (b) Options:
    1. In-place dock reframe, keep AppId-keyed window navigation — cheapest, preserves the OS feel and multi-window runtime; no react-router. (S00 §9 Q1Q2 recommendation.)
    2. Left rail + react-router routes — closer to the mock, gains deep-linking, but a parallel layout + conflicts with multi-window; large blast radius.
  • (c) RECOMMENDED: (1) In-place dock reframe; keep windowed AppId navigation. Group dock entries into Work / Intelligence / Extend / Team zones to satisfy the IA without a router. Rationale: PRD §24 (mocks directional) + locked in-place direction. Revisit deep-linking only if it becomes a hard requirement.
  • (d) Blocks: Phase 0 → Phase 1 (AppShell/IA, S00) — and the dock/AppId placement of S11/S20 ("automations" zone) and S01 (home vs cockpit). [BLOCKS P1] — the IA freeze gates everything.

B2. Memory confidence — heuristic-at-preview vs LLM-classify, and persisted vs preview-only?

(Gap cards S04 §9 Q1, S16 §9 Q1Q2; S15 §9.)

  • (a) Why it matters: memory_frames has no confidence today (only knowledge_relations.confidence, edges-only, schema.ts:93). PRD §12.4 wants "filter by confidence" + "low-confidence surfaced for review", and onboarding Memory Review (S16) + the standing J08 review queue both depend on it. Wiring the existing HarvestPipeline classify/synthesize means paid Haiku/Sonnet calls per import (slow, gated on a real embedder); a cheap heuristic avoids that.
  • (b) Options:
    1. Cheap heuristic at preview (source-trust × adapter-type × dedup signal), persisted in metadata when a queryable filter is needed — fast, no per-import LLM cost; reserve LLM scoring for an opt-in deep pass / the J08 standing queue. (S16 §9 Q1 recommendation.)
    2. LLM classify/synthesize at preview — real confidence, but onboarding-latency + cost hit.
    3. No confidence v1 — drops a core PRD trust requirement (§12.4).
  • (c) RECOMMENDED: (1) Heuristic for onboarding v1; LLM classify reserved for the standing J08 queue. Persist {kind, confidence, sourceId, status} in the existing memory_frames.metadata TEXT via the idempotent ADD COLUMN pattern (db.ts:122) only if confidence/status become queryable filters; preview-only needs no migration. Make this one decision once and reuse it across S04 + S16. Rationale: honors PRD trust criteria within the onboarding latency budget, local-first, one additive migration at most.
  • (d) Blocks: Phase 2 — onboarding Memory Review (S16, a day-0 J01 flow) and Memory Center filters (S04). [BLOCKS P2]. Shares the migration with A8.

B3. Agent vs Persona boundary, and where the Agent entity is stored.

(Gap cards S09 §9 Q1, Q3; S18 §9 Q1, Q2.)

  • (a) Why it matters: Decides whether Phase 3 introduces a real persisted Agent object (distinct from the 13/17 personas in persona-data.ts) or just re-skins the persona catalog. PRD §15.5 lists explicit agent fields (model, autonomy, memoryScopes, skillIds, connectorIds, mcpIds, permissions, …) that a persona does not carry.
  • (b) Options:
    1. Real Agent entity in a JSON store ({dataDir}/agents.json), referencing personaId — no .mind migration, mirrors the agent-groups.json precedent; persona = behavioral template field of the agent. (S09 §9 Q1/Q3 + S18 §9 Q1/Q2 recommendation.)
    2. agents table in mind/schema.ts (SCHEMA_VERSION bump) — heavier; PRD §4.4 non-goal favors minimal backend.
    3. No Agent entity; persona re-skin only — can't satisfy PRD §12.9 explicit-scope requirements.
  • (c) RECOMMENDED: (1) Real Agent entity, JSON store, references personaId. Derive successRate/lastRun at read from execution_traces (avoid a third tally vocabulary). Rationale: satisfies PRD §12.9/§15.5 with zero migration, in-place over the existing fleet/traces substrate.
  • (d) Blocks: Phase 3 (Agent Center S09 + Agent Builder S18). Not P1/P2.

B4. /api/* vocabulary aliasing — singular command, automations, mcps, connectors revoke.

(Gap cards S03 §9 Q1, S11 §9 Q4, S20 §9 Q4, S07 §9 Q3; backend-api-delta.)

  • (a) Why it matters: PRD §16 uses vocabulary (/api/command/*, /api/automations/*, /api/connectors/:id/revoke) that differs from the live routes (/api/commands/execute, /api/cron/*, /api/connectors/:id/disconnect). Renaming breaks existing callers (adapter.executeCommand, commands.ts, cron.ts); aliasing keeps both contracts.
  • (b) Options:
    1. Add PRD-vocabulary aliases alongside the live routes — new command.ts/automations.ts alias plugins that delegate to the existing registry/cron; existing callers unbroken. (S03/S11/S20 recommendations converge on this.)
    2. Hard-rename to PRD vocabulary — clean surface, but breaking; needs exhaustive grep (CLAUDE.md §3.5).
  • (c) RECOMMENDED: (1) Alias, don't rename. New singular/plural aliases that delegate to the existing handlers; UI/adapter point at the PRD vocabulary. Rationale: in-place, non-breaking, matches the backend-api-delta dispositions.
  • (d) Blocks: Phase 1 (Command Center S03) for /api/command/*; Phase 3 (S11/S20) for /api/automations/*; Phase 4 (S07) for connector revoke. The command alias is [BLOCKS P1].

B5. Tier-vocabulary unification (UserTier / BillingTier / PlanTier + RBAC roles).

(Gap cards S00 §9 Q3, S08 §9 Q6.)

  • (a) Why it matters: Three independent tier vocabularies gate the dock, billing, and feature access; PRD §17 RBAC roles add a 4th axis. MCP Hub (S08) and the dock (S00) both need a single answer for "is this gated PRO+ or power-user-density".
  • (b) Options:
    1. Document the mapping, defer unification — keep the three vocabularies, ship a single mapping table and a useFeatureGate that reads the canonical tiers.ts; no cross-cutting rewrite now.
    2. Unify into one tier model now — clean, but cross-cutting (billing + dock + features + RBAC) during a high-velocity refactor.
  • (c) RECOMMENDED: (1) Document the mapping + route all new gates through @waggle/shared tiers.ts (TierCapabilities); defer the unification refactor. Gate MCP Hub + Marketplace install at PRO+ (matches the existing marketplace install gate). Rationale: avoids a cross-cutting rewrite mid-refactor; reuses the canonical tier system; no parallel gate (S10 §6).
  • (d) Blocks: Phase 4 (S08 tier gate) primarily; informs the dock gate in Phase 0/1. Not P1 blocking if the mapping is documented.

B6. MemoryKind / ImportItemType / FE MemoryFrame.type reconciliation.

(Gap cards S04 §9 Q6, S16 §9 Q3.)

  • (a) Why it matters: Three vocabularies disagree: FE MemoryFrame.type (event/insight/…), PRD §15.2 MemoryKind (fact|decision|task|preference|strategy|learning|goal|entity), and the harvest adapter's 8 ImportItemType values. Memory Review categories (Memories/Decisions/Tasks/Artifacts/ Projects) need a 1:1 map. Wrong choice re-renders existing frames and changes the type-filter chips.
  • (b) Options:
    1. Adopt PRD §15.2 MemoryKind as canonical; add a pure lib/harvest-kind-map.ts mapping ImportItemType → MemoryKind and a display-category map — drop FE event/insight, add preference/strategy/learning/goal. (S04 §9 Q6 + S16 §9 Q3 direction.)
    2. Keep FE types, map PRD onto them — less churn now, perpetuates drift (precedent: the FrameSource TS-vs-DB drift the shared-types-delta warns against).
  • (c) RECOMMENDED: (1) PRD §15.2 MemoryKind canonical, in @waggle/shared; pure mapping helpers for harvest + display categories. Rationale: one source of truth (shared-types-delta §0 rule), avoids perpetuating drift, keeps the import/review/center contract consistent.
  • (d) Blocks: Phase 2 (S04 + S16). [BLOCKS P2].

B7. ExtensionType union — add agent, keep external_tool, or both?

(Gap card S21 §9 Q1; PRD §12.13 vs §15.2.)

  • (a) Why it matters: PRD §12.13 marketplace categories include Agents but ExtensionType (§15.2) omits agent and adds external_tool. The two PRD sections contradict; S21's faceted catalog needs a canonical union.
  • (b) Options:
    1. skill | agent | connector | mcp | model | template — matches the §12.13 visible categories; drop external_tool (external tools surface via connectors/MCPs anyway).
    2. Keep §15.2 literally (…| external_tool, no agent) — but then Agents have no marketplace category.
    3. Superset of 7 (…| external_tool | agent) — covers both, at the cost of an unused-for-now member.
  • (c) RECOMMENDED: (1) skill | agent | connector | mcp | model | template. Rationale: PRD §12.13 is the user-visible contract; external tools are already represented by connectors/MCPs, so agent earns the slot. Define once in @waggle/shared.
  • (d) Blocks: Phase 4 (Marketplace, S21). Not P1/P2.

B8. Identity store of record for onboarding profile.

(Gap card S13 §9 Q1; S01 §9 (greeting name).)

  • (a) Why it matters: Two identity stores exist — /api/profile (current onboarding write path) and /api/identity (the identity table that backs the Home greeting name / adapter.getIdentity()). Writing only one leaves the other stale (e.g. Home greets with an empty name).
  • (b) Options:
    1. Onboarding writes profile AND seeds identity — single round-trip extension; Home greeting works immediately. (S13 §9 Q1 direction.)
    2. Profile-only, derive identity lazily — fewer writes, but Home greeting drift until first identity write.
  • (c) RECOMMENDED: (1) Write profile + seed identity in the same onboarding commit. Rationale: prevents the two-store drift the gap card flags; cheap; makes the Phase-1 Home greeting correct.
  • (d) Blocks: Phase 2 (onboarding S13) and the Phase 1 Home greeting depends on identity being populated. Practically [BLOCKS P1] for a correct greeting; functionally a small fix.

§C — Screen-local questions (single-screen scope; ratify with the owning card)

These do not block other screens. Each carries a default recommendation consistent with the locked direction; founder can rubber-stamp or override per screen. Cited to the gap card for full context.

  • C1. S01 Q1 — LoginBriefing fate. Retire the modal; absorb catch-up into Home Cockpit's first paint (~80% overlap). Rec: retire + absorb. (Phase 1.)
  • C2. S01 Q2 — "Overnight" time-window semantics (since last close vs midnight vs 12h). Rec: since last app close, fallback midnight-local. (Phase 1.)
  • C3. S01 Q6 — Quick-capture file destination (default/personal store vs prompt for workspace). Rec: default personal store + optional workspace picker. (Phase 1/2.)
  • C4. S02 Q1 — Workspace Desktop window vs full-bleed route. Rec: maximized AppWindow (no parallel layout system). (Phase 1.)
  • C5. S02 Q2 — Overview chat: live mini-composer vs read-only preview. Rec: read-only preview that deep-links to the Chat tab (avoids dual ChatApp render modes in v1). (Phase 1.)
  • C6. S02 Q3 / S17 Q1 — WorkspaceType enum values. Rec: project | client | research | personal (+team/organization reserved); type coexists with the free-string group. (Phase 1/2.)
  • C7. S02 Q6 — Tasks store of record (/api/workspaces/:id/tasks vs WorkspaceState pending/blocked). Rec: seed Tasks from WorkspaceState for v1; reconcile to a first-class task store only if editing is needed. (Phase 1.)
  • C8. S03 Q4 — Natural-language commands (heuristic vs LLM). Rec: deterministic heuristic intent-parse v1; LLM resolver later. (Phase 1.)
  • C9. S03 Q5 — Palette permission prompt mechanism. Rec: reuse the chat approvals pipeline (approval.ts + pendingApproval). (Phase 1.)
  • C10. S04 Q2 — Conflict state: live recall-time vs persisted. Rec: live recall-time signal v1 (CombinedRetrieval.detectConflict); persist only if a standing conflict queue is needed. (Phase 2.)
  • C11. S04 Q4 — Merge semantics. Rec: re-cognify/concatenate v1, archive originals (not hard delete); LLM-synthesis later. (Phase 2.)
  • C12. S05 Q5 — Artifact previews. Rec: icon + on-click FilePreview v1; no server thumbnails. (Phase 2.)
  • C13. S06 Q2 / S19 Q1 — Skill Builder publish target (local dir vs marketplace). Rec: Builder = create-to-local (POST /api/skills/create); install-by-id + marketplace publish live in S06/S21. (Phase 3.)
  • C14. S06 Q4 / S19 Q2 — Inputs/Outputs persistence (frontmatter vs body markdown). Rec: body markdown v1; extend SkillFrontmatter only if inputs/outputs must be queryable. (Phase 3.)
  • C15. S06 Q6 / install-audit critical CHECK bug. Real bug: AuditRiskLevel TS includes critical but the DDL CHECK allows only low/medium/high (install-audit.ts:65 vs :16) — a record() with critical throws; skill/MCP/connector installs route through this path. Rec: ship the one-line CHECK migration to add critical (additive, idempotent-migration pattern at db.ts:122), OR make the marketplace CRITICAL → 'high' + approvalClass:'blocked' mapping the permanent contract. Pick the migration for correctness. (Phase 4; cross-cuts any install-audit write.)
  • C16. S07 Q1 — Connector "sync now" semantics. Rec: v1 = re-probe health + stamp lastSyncAt; background data re-pull deferred. (Phase 4.)
  • C17. S07 Q3 — revoke vs disconnect. Rec: revoke purges OAuth tokens + writes a stronger audit entry (PRD §17.3); disconnect is the lighter alias. (Phase 4.)
  • C18. S07 Q4 / S08 — Audit route shape. Rec: one shared GET /api/extend/audit?type= serving connectors + MCPs + marketplace, bound to personal.mind. (Phase 4.)
  • C19. S08 Q2 — MCP scope model (single workspaceId vs mcpIds[] N:N). Rec: single-workspaceId config v1 (matches the stdio runtime); N:N membership deferred. (Phase 4.)
  • C20. S08 Q4 — "Remote Registry" tab. Rec: defer remote-transport MCPs (runtime is stdio-only); v1 tab points at the static catalog / Composio gateway reference, no new transport. (Phase 4.)
  • C21. S08 Q5 / S21 Q5 — MCP "test" semantics. Rec: live spawn-and-isHealthy()/tools/list round-trip where cheap; fall back to static manifest validation. (Phase 4.)
  • C22. S09 Q6 — Agent categories taxonomy. Rec: Templates is a side affordance, not a tab; tabs = All/Personal/Workspace/Team/Autonomous/Archive. (Phase 3.)
  • C23. S09 Q7 / S18 Q3 — /run target + lifecycle. Rec: fleet-spawn a one-shot into a chosen workspace (picker if multiple workspaceIds); persistent always-running agents deferred. (Phase 3.)
  • C24. S11 Q1 / S20 Q1 — Automation triggers: schedule-only vs event-driven. Rec: schedule-only v1 (cron cadence); gate/defer the "Event" trigger (no event→automation dispatch substrate today). (Phase 3.)
  • C25. S11 Q2 / S20 Q2 — Condition step. Rec: store an advisory jobConfig.condition string (no evaluation engine) v1. (Phase 3.)
  • C26. S11 Q3 / S20 Q3 — Builder "test run". Rec: add a no-persist dry-run route (POST /api/automations/test); do NOT reuse the real cron/:id/trigger which executes + auto-enables. (Phase 3.)
  • C27. S11 Q6 — Analytics tiles. Rec: keep success-rate (derivable from cron_execution_history); drop "hours saved" (no source) or label it an explicit heuristic estimate. (Phase 3.)
  • C28. S12 Q1 — Onboarding language selector. Rec: static disabled English (US) chip (no i18n exists; PRD §4.4 puts i18n out of first-phase scope). (Phase 2.)
  • C29. S12 Q2 — First-launch 3s auto-advance on the privacy screen. Rec: drop the auto-advance (it fights the read-the-privacy-note intent). (Phase 2.)
  • C30. S13 Q3 — Work-type vs Industry vs Template axis. Rec: keep Work type as a distinct personalization signal; don't re-ask what the template already implies (PRD §12.12). (Phase 2.)
  • C31. S14 Q2 — Tool Discovery id-space. Rec: unify under a namespaced scheme (connector:gmail / tool:cursor) so the recommender + S15 disambiguate. (Phase 2.)
  • C32. S14 Q3 — Pre-check detected AI tools. Rec: pre-select from GET /api/tools/detect with a visible "detected" badge (J01 implies a trusted populated start). (Phase 2.)
  • C33. S15 Q2 / S16 Q5 — Import↔Review commit split. Rec: S15 stages previews, S16 commits the approved selection (PRD:646/1207 "nothing imports without review/approval"; current code commits at S15 — fix). Splits onboarding into the Import + Review steps. (Phase 2; correctness-relevant.)
  • C34. S15 Q1 — Hermes/Codex/Cursor tiles. Rec: render as upload/"Other" file pickers or "coming soon" v1 (they are AI-OS launcher/hook surfaces, not harvest adapters). (Phase 2.)
  • C35. S17 Q5 — Workspace Creation: install-on-create vs stage selections. Rec: record connector/ MCP ids as workspace intent on the config; do NOT run install/OAuth at create time. (Phase 2.)
  • C36. S19 Q4 — Skill scope vocabulary (enterprise vs PRD organization). Rec: adopt PRD organization for the publish-scope picker (align to the §15.2 Scope union). (Phase 3.)
  • C37. S19 Q5 — Skill test-run fidelity. Rec: preview-only (injected-prompt + parsed metadata) v1; live LLM dry-run deferred. (Phase 3.)

Phase-blocking summary (founder fast-path)

Before Phase 0/1 coding (the spine): RATIFIED 2026-06-09B1 (shell topology / IA freeze), A1 (fixed layout), A2 (Home personal-only), B4 (command alias), B8 (identity seed for greeting). Phase 0 is unblocked.

Must ratify before Phase 2 (work + onboarding): A6 (artifact storage entity), A8 (memory retention/delete), B2 (confidence: heuristic + optional migration), B6 (MemoryKind canonical), A3 (graph keep — default yes), plus the onboarding correctness item C33 (Import stages / Review commits).

Phase 3+ (intelligence/extend/team), not blocking P1P2: A4, A5, A7, B3, B5, B7 + all remaining §C items. Note A7 (RBAC) must be ratified before S10 coding specifically, and C15 (install-audit critical CHECK bug) should be fixed before any install-audit write path ships in Phase 4.


UX Refactor v2.1 — Ratification of Decision Register D1D15 (2026-06-10)

Ratifies: docs/UX_REFACTOR_STATE_AUDIT.md §8.3 · Ratified by: Marko Marković (founder) Authority chain (declared by this register, D10): this ratification > Brief v2.1 > docs/UX_REFACTOR_STATE_AUDIT.md > blueprint handoff package > prior-plan docs (docs/ux-refactor/). This document + Brief v2.1 + the audit supersede all prior conflicting ratifications, explicitly including B1 (2026-06-09). This file is the single decision log going forward — no parallel ratification tracks.

Structural (D1D5)

D1 — Shell topology: RATIFIED option (b) — AppShell via in-place conversion. B1 is explicitly superseded.

Convert to AppShell + left nav + single canvas + URL routes, reusing every shipped screen component as a route surface. Conditions:

  1. Zero screen-component rewrites during conversion; screens mount under routes as-is. Divergences are phase work, not conversion work.
  2. Brief route groups become canonical addresses; Ctrl+K command index and handleSearchNavigate retarget to routes; waggle:open-app CustomEvent deep links convert to URL navigation (the event bus may remain as an internal shim during transition, but URLs are the contract).
  3. No window z-order code ships (useWindowManager z-order/focus/minimize/cascade retired). waggle-window-state-v1 localStorage migrates or clears cleanly.
  4. Chat multi-instance: chat becomes the widget inside Workspace Desktop (one per workspace, per blueprint "chat is one widget"). If conversion design surfaces a hard requirement for detached chat, propose it as a scoped exception ("D1-c lite") — do not silently keep windowing.
  5. B4 ("alias, don't rename" for /api/*) survives — orthogonal to the shell and correct.

D2 — Memory Center: RATIFIED — rework AND promote to standalone.

Standalone MemoryCenterApp (same shape as ArtifactCenterApp; audit §7.9 inconsistency resolved in favor of the standalone pattern). Top-level structure = two-mind split: "About you" (Personal Mind) / "About this work" (Workspace Mind, per workspace). Reuse MemoryCenterTab internals as the per-mind list. Confidence/metadata (B2, M1) carry over. Legacy MemoryApp tabs (Graph/Timeline/etc.) remain accessible from within the new surface or as secondary tabs — do not delete capability, restructure the entry.

D3 — Auth gate: RATIFIED — full structural scope. All four audit conflicts in scope:

  1. Adapter-level pre-token deferral (structural gate, not per-component convention).
  2. Throw-on-!ok mandated adapter-wide — convert all silent-empty getters (getMarketplace, getMcps, getPersonas, getModels, getWorkspaceTemplates, getTier).
  3. 401 → silent token refresh → single retry (sidecar-restart recovery) — in scope.
  4. Boot-path surfaces in scope: Desktop.refreshTier and LoginBriefing must never render silent-FREE / silent-empty on auth failure. Tier resolution failing open to a rendered FREE state is classified as a monetization defect, severity-critical. Plus: error states never cache as valid-empty; focus/visibility revalidation on errored surfaces.

D4 — Skill-write governance: RATIFIED — autonomy-aware gating, four bindings:

  • (i) Policy: create_skill — normal autonomy = ask (in-chat approval card), trusted/yolo = auto-execute. delete_skillalways ask, every autonomy level (add to isCriticalNeverAutopass); destructive actions do not inherit autonomy. read_skill ungated. Always-audit all three outcomes with initiator:'agent'.

  • (ii) Surface: the in-chat SSE approval card is canonical for agent skill writes. Brief §2.3's "same modal" is hereby interpreted as same policy and risk taxonomy, not same component. Align the card's risk display with the ui/approval-modal.tsx taxonomy (D15 work).

  • (iii) One write path — AMENDED ruling: do NOT route the agent tool through HTTP. Extract a shared skill-write service module (create/update/delete + redaction + audit write inside the service) consumed by both routes/skills.ts and skill-tools.ts. One module, one audit trail, two callers.

  • (iv) Endpoint consolidation (absorbs D14): raw POST /api/skills delegates to the audited service (or is deprecated in favor of /api/skills/create); PUT and DELETE /api/skills/:name enter the audit trail. Provenance: skill frontmatter initiator/source + GET /api/skills returns it + Skills Hub badge ("created by agent — review"), replacing the name-heuristic "Custom" classification for agent-created skills.

  • Persona exception RATIFIED: read-only personas (planner/verifier) keep losing create_skill/delete_skill while retaining read_skill.

  • PM residual ruled (PRO-gate on skill creation): skill creation — human and agent — stays available at FREE for launch. The self-evolving loop is the differentiator and must demo at the free tier. Marketplace installs remain PRO-gated. Reversible post-launch with data.

  • Two-seam WorkspaceDesktopApp edit RATIFIED (founder "go", 2026-06-10): the derived edit from plan §5.2 — (a) controlled activeTab/onTabChange for URL-driven tabs, (b) chat widget embedded in the chat tab body — is signed off, scoped to exactly those two seams, test-pinned. P1a unblocked.

D5 — Team zone: RATIFIED — keep tier-hidden. No stripping, no new work. Approvals-inbox PRO visibility: post-launch consideration, not launch scope.

Scope clarifications (D6D10) — defaults ratified, with notes

  • D6 — RATIFIED. S14-in-Launcher and S16-as-needs-review-filter satisfy the launch cut. Consent is given at import initiation; review is quality control, not consent. Verification item: Home Cockpit must surface a "N memories need review" alert (journey J08); if absent, add as a small Phase-2 item.
  • D7 — RATIFIED. UpgradeModal satisfies §2.2; no rename, no rebuild — tests pin it. Brief language amended to "Upgrade surface."
  • D8 — RATIFIED. Relabel dock cockpit entry ("Mission Control"); "Command Center" is reserved for the Ctrl+K palette.
  • D9 — RATIFIED. Sweep: code (the HomeCockpit.tsx:145 user-visible "Win+K" pill is the must-fix; comments included) + docs/ux-refactor/ prose. Handoff-package PDFs/docx get a one-page annotation (naming erratum), not regeneration.
  • D10 — RATIFIED, extended. Commit the package's text files; gitignore (or LFS) the binaries. Authority chain declared (header above). Prune merged worktrees (waggle-os-ux-refactor, waggle-os-ga) and the 5 merged branches. Brief path corrections from audit §7 accepted (workspace-manager in hive-mind-core; state/context in server/local).

Launch integrity (D11D15) — all confirmed

  • D11 — RATIFIED. Honor WAGGLE_DATA_DIR in service.ts with the same default; one startup log line: resolved dataDir + tier. Fix the stale "default to SOLO" comment while in there. Closes the split-brain with installer/launcher.
  • D12 — RATIFIED, launch-blocking for the desktop binary. Refresh app/src-tauri/resources/service.js now; prefer build-time generation + untracking; CI staleness/hash gate is the minimum acceptable. A binary shipping an April server is a release-stopping defect class.
  • D13 — RATIFIED, both halves. Document build:packages in the boot recipe AND alias @waggle/shared→src on the dev path so the class dies.
  • D14 — Folded into D4(iv). Closed.
  • D15 — RATIFIED. Launch-blocking from prior-plan P6: per-screen state grid (brief rule 10) + approval/audit taxonomy consolidation (brief rule 7, includes D4-ii alignment). Post-launch: connector /sync real implementation (stub stands), MCP logs.

Additional items (no decision letter — just do)

  • Backlog flag: investigate the teams-server boot error from the live probe (Build failed: Fastify instance is already listening when CLERK_SECRET_KEY is set) — classify noise vs defect. Post-launch unless it affects the solo boot path.
  • memory-mcp duplication (audit §7): out of launch scope. Mark packages/memory-mcp dormant; canonical-package decision (vs hive-mind-mcp-server) deferred post-launch.
  • WorkspaceBriefing.tsx: keep as ChatApp empty state; no merge into Home. Brief's keep-list note corrected.
  • Audit process rule going forward: audits report, they don't mutate (no fast-forwards, no pid overwrites mid-audit; disclose if unavoidable).

Phase sequence (unblocked)

Phase 0 = D1 conversion plan + route map, naming sweep (D8/D9), doc authority (D10). Then P1=D3, P2=verify + J08 alert, P3=D2, P4=D11/D12 + FREE→Upgrade e2e re-run, P5=D4 (2026-06-12, 7 commits 73f2ed5→48292ef), P7=D15 scope (2026-06-12: Track B B1-B5 + Track A A1-A7; D15 closure bar MET). Nothing from prior Phases 04 is rebuilt.


D3 implementation notes (P1b, 2026-06-11)

Recorded per the single-decision-log rule; full design + verification record in docs/ux-refactor/p1b-auth-gate-plan.md + p1b-plan-review-record.md.

  1. fetchRaw exception class — ratified-flow-preserving deviation from the literal "throw mandated adapter-wide" (D3-2). Two caller classes keep non-throwing semantics because their error-path payload is load-bearing: raw-Response consumers (installMarketplacePackage — documented 403/SecurityGate status handling) and body-envelope getters (installMcp + 6 MCP siblings + revokeConnector — their 403/422 bodies carry TIER_INSUFFICIENT and the requiresApproval/blocked/severity envelope that drives the D4 ApprovalModal security flow). All six ruling-named getters throw as mandated. Adapter-level envelope pins added (component tests mock the adapter and cannot see this layer).
  2. Plus-clause revalidation scope. Wired: tier (ShellContext), useBilling, useWorkspaces, LoginBriefing, MCPHubApp resolvableMcpNames, ComplianceDashboard templates. Deferred to P7 with ledger: ChatWindowInstance FALLBACK_MODELS, TemplatesView/AgentBuilder catalogs (their boot-race instance dies with the gate; the 401-retry leg cures their restart instance; residual is genuine-5xx staleness).
  3. D3-4 extensions (same monetization-defect class): useBilling (Settings→Billing rendered FREE-as-fact + upgrade CTAs on failure) and the Settings→General "{tier} plan" badge (separate getSettings-fed copy, now single-sourced from resolved billing state).
  4. DISCOVERED, OUT OF P1b SCOPE — needs a founder ruling: all five EventSource SSE channels (notifications / events / subagent status / waggle signals / harvest progress) are 401-dead in every default run since D1 — the server bearer-gates all /api/* GETs, EventSource cannot send headers, no SSE route accepts ?token= (only /ws does), and onerror handlers permanently close. Working only under WAGGLE_TRUST_LOCALHOST=1. Fix = server auth model (per-route ?token= like /ws, or exempt-with-validation) + client reconnect design — one coherent follow-up ("SSE auth + reconnect"). Ask: ratify as P1b follow-up stage or P2 line item.

P2 implementation notes (verify + J08, 2026-06-11)

Recorded per the single-decision-log rule; full record in docs/ux-refactor/p2-verification-record.md.

  1. P2 verification CLOSED. Home (§12.1) + Desktop (§12.2) verified against Brief v2.1 via a 4-lane adversarial workflow: 25/37 met or ratified-divergence, 12 confirmed gaps, 2 claims refuted. The HIGH (dead Artifacts feed — envelope unwrap) + all tiny/small verified defects fixed; feature-shaped residuals ledgered in the record (S02 tab embeds → P3/P7; status-bar chips, upNext tasks, activeModels → P7).
  2. D6 J08 alert SHIPPED. needsReviewCount rides GET /api/home/briefing (personal-mind only, 200-frame bound matching the Memory Center's own window); Home banner deep-links via waggle:open-app {appId:'memory', filter:'unreviewed'} with a ?filter= URL carrier + MemoryRoute cold-load re-stash (typed URLs and the §2.3 shim share one mechanism, AutomationsRoute pattern).
  3. D3-4 extension: WorkspaceDesktop revalidation arms only for the transient offline state — deterministic 404/403 states do not auto-refetch on focus.
  4. Note (P1b-SSE follow-up): the SSE ask above was ratified and SHIPPED as a P1b follow-up (PR #15, main @ 4e3d65d) — closed before P2 started.

P3 implementation notes (D2 two-mind Memory Center, 2026-06-11)

Recorded per the single-decision-log rule; full design + live-run findings in docs/ux-refactor/p3-memory-center-plan.md.

  1. D2 SHIPPED in full. Standalone MemoryCenterApp (ArtifactCenterApp shape, fully controlled — URL is the only navigation authority): mind pills "About you" / "About this work · {ws}" on the Memories view; all six legacy MemoryApp views survive as secondary tabs (Timeline extracted verbatim to memory/TimelineTab.tsx; MemoryApp.tsx retired — capability preserved, entry restructured). /memory/:mindScope + ?tab= implemented (conversion plan §5.3 #1-2 closed); ?filter= J08 stash unchanged. S02-FR2 Memory part closed: WorkspaceDesktop memory tab embeds the per-mind list (consumeDeepLinks=false so the J08 stash stays with the /memory route).
  2. Server contract (additive): GET /api/memory?mind=personal|workspace selects one store; invalid mind or workspace-less mind=workspace is a 400 (a typo must not silently become the merge view); omitted mind keeps the legacy merge (pinned). Workspace-mind mutations now carry workspace from the FE — without it, PATCH/archive/delete/merge missed the workspace store entirely (404 class, fixed + pinned).
  3. Cross-mind id-collision class: per-mind SQLite autoincrements collide; the split makes every view single-mind (mutation ambiguity structurally gone from the new UI); selection + list clear on mind switch (cross-mind merge / stale-rows-under-wrong-pill pins). Full id namespacing remains post-launch.
  4. Live-run defects fixed (pre-existing, surfaced by the mandatory smoke): KnowledgeGraphViewer crashed the surface on untyped entities (54/214 real rows; fixed via single-entry node normalization, 'unknown' legend chip); Timeline duplicated React keys on cross-mind id 36 (fixed via mind-qualified keys).

P4 implementation notes (D11 + D12 + clean-install onboarding, 2026-06-11)

Recorded per the single-decision-log rule; full record in docs/ux-refactor/p4-launch-integrity-record.md.

  1. D11 SHIPPED. resolveDataDir() = option > WAGGLE_DATA_DIR > ~/.waggle (split-brain with installer/marketplace/memory-mcp closed); the ratified one-line startup log Data dir: <resolved> · tier: <effective> via readTierFromDataDir (extracted; same config.json + getEffectiveTier contract as GET /api/tier); both stale SOLO comments fixed. Live-verified: env-pointed boot logged the tmp dir + tier FREE.
  2. D12 SHIPPED — preferred shape (generation + untracking). service.js/.map untracked + gitignored; tauri.conf.json beforeBuildCommand owns the full prep chain so a raw npx tauri build ships a CURRENT server (previously: the April copy). Dev mode unaffected (service.rs debug branch spawns service.ts via tsx). Pinned in tauri-config.test.ts.
  3. S4 founder flag RESOLVED — the clean-install skip was REAL. ensureDefault() at boot + the getWorkspaces().length > 0 auto-complete evidence meant brand-new production users never saw the wizard. Fix: server-authoritative GET /api/onboarding/status (completion flag <dataDir>/first-launch.flag — same file as the Tauri IPC stamp — OR legacy evidence: any personal-mind frame / >1 workspaces; the seeded stub is NOT evidence) + POST /api/onboarding/complete stamped from useOnboarding.update() on completion. Fail direction: toward showing the wizard. Live-verified clean dataDir → completed:false. Accepted edge: a pre-flag returning user with zero frames + only the default workspace re-sees the wizard once (no durable signal can distinguish them; class dies as flags stamp).
  4. FREE→Upgrade e2e re-ran: Act 4 Tier Wall 6/6 on a fresh FREE install under WAGGLE_TRUST_LOCALHOST=1; the unauthenticated first run's 3 failures are the documented dock-era-spec-vs-P1b-bearer-gate class — spec-side token wiring stays ledgered with the P7 e2e band.
  5. Two-round adversarial review (19 confirmed total / 34 refuted) — all confirmed findings fixed, headlined by: a HIGH in P4's own first cut (the D12 hook re-ran arch-parameterized bundle scripts arch-blind — cross-arch macOS release legs would ship a non-launching Intel DMG; hook trimmed to the arch-independent sidecar bundle + a fail-loud resources preflight); a verified MED chain where the wizard's own step-1 profile write counted as returning-user evidence (server-durable PENDING latch added — only explicit completion flips status once a dataDir is identified as un-onboarded); the Tauri fs-flag now honors WAGGLE_DATA_DIR (Rust) so the IPC fast-path and the server stamp share one file on every install shape; and the sidecar bundle now compiles @waggle/shared/@waggle/hive-mind-core from SOURCE (esbuild alias — the regenerated bundle used to embed stale gitignored dist silently). Full dispositions: docs/ux-refactor/p4-launch-integrity-record.md.