Skip to content

test/docs(floating): reconcile INTERACTION.md + smokes to resting-purity reality (S6)#160

Merged
gorajing merged 8 commits into
mainfrom
feat/floating-reconcile
Jul 4, 2026
Merged

test/docs(floating): reconcile INTERACTION.md + smokes to resting-purity reality (S6)#160
gorajing merged 8 commits into
mainfrom
feat/floating-reconcile

Conversation

@gorajing

@gorajing gorajing commented Jul 4, 2026

Copy link
Copy Markdown
Owner

S6 — the FINAL slice of the floating-UI redesign. Reconciles the docs + smokes to the shipped reality (S1–S5 + S4b merged). No product code changes — docs + smoke scripts only.

INTERACTION.md (the LOCKED contract) — full rewrite

From the deleted-"Ask pill" model to pure-cat-at-rest: resting = just the cat on the transparent click-through window; tap/hold=pet (sacred), drag=move, tap never summons; summon via ⌘⇧Space or hover→#ask-handle menu→#menu-ask; each tethered #roro-stage reaction documented (input bubble, #working-chip, #floating-error AlertCard, #roro-speech + truthful receipt, Ask·Memory·Project menu + Memory/Project popovers). Gesture Design Laws preserved. Every id verified to exist in the code; stale "ask pill" refs across docs/ swept to 0.

Smokes reconciled against LIVE runs

  • 4 non-CI packaged smokes (epipe, model-setup, first-task, onboarding): the stale body.innerText.includes('Roro') "not blank" proxy (the pill's text is gone) → stageMounted: !!#roro-stage (the renderer-executed signal), gating the dom-ready poll on it to avoid a capture race (per smoke-packaged-memory). All 4 PASS live.
  • smoke-floating-menu (c)/(d): were clicking HIDDEN menu items (the menu steps aside when a popover opens) → now dismiss the popover, re-hover to RE-REVEAL the menu, assert the item is visible + hit-tested + doesn't wake the cat, THEN click. PASS live (independently re-run).
  • floating / floating-geometry / floating-live-turn: all run + PASS.
  • onboarding: added RORO_FLOATING_WINDOW=0 (Settings moved to the floating popover in S4b; matches sibling packaged smokes) — a stale-smoke reconcile, not a product change.

Gate

tsc clean · 1088 passed / 11 skipped (exact baseline) · eslint 0 errors · docs pill-refs 0.

🤖 Generated with Claude Code

gorajing and others added 2 commits July 4, 2026 06:02
…el (S6)

Reconcile the LOCKED interaction contract + related docs to the shipped
floating-redesign reality (S1–S5 + S4b merged). Drop the always-visible "Ask
pill" model; document:
- resting state = just the cat on a transparent, ~80% click-through window;
- the two body verbs (tap/hold = pet, sacred + unchanged; drag = move window);
- the two summon paths (⌘⇧Space, or hover-dwell → #ask-handle menu → #menu-ask);
- each tethered #roro-stage reaction: input bubble (#floating-ask/#ask-input),
  WorkingChip (#working-chip/#working-stop), AlertCard (#floating-error,
  classified errors), SpeechBubble (#roro-speech + the truthful "used what I
  remember about your setup" receipt), and the Ask·Memory·Project menu +
  tethered Memory/Project popovers;
- the click-through mechanics (setIgnoreMouseEvents + the marker hit-test).
Preserve the Gesture Design Laws (disambiguate by surface+button+state, never
timing; always pettable; real interactions reset the sleep timer; gaze/hover
never wakes the cat). Every id/claim cross-checked against the renderer/window
code.

Also sweep stale "pill" references to the summon paths in PRODUCT_PLAN,
VERIFICATION, floating-redesign, and the paw-on-the-pixel plan/handoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rity reality (S6)

Packaged smokes — the innerText.includes('Roro') "not blank" proxy broke when
the pill was deleted (it passed off static index.html even if the renderer never
executed). Replace it in all four non-CI packaged smokes with the renderer-
executed signal the CI-gating memory smoke already uses: capture
stageMounted = !!document.getElementById('roro-stage') and assert THAT. Gate the
dom-ready poll on stageMounted too, so a snapshot can't race a blank frame
(epipe gated on static #topbar/#prompt-form + preload bridge — all present
before bootstrap runs). Files: epipe, model-setup, first-task, onboarding.

onboarding also had 3 PRE-EXISTING failures (reproduced on origin/main): it ran
in the default floating window, where S4b moves Settings into the hidden Project
popover, so #project-settings-toggle is present-but-hidden and its visibility
assertions failed. Add RORO_FLOATING_WINDOW=0 to exercise the framed onboarding
UI, matching the sibling packaged smokes (model-setup, first-task). The floating
pet's own surfaces stay covered by the on-screen smoke-floating-* suite. Not a
product bug — the moat surface is reachable via the hover menu.

floating-menu (c)/(d) — they clicked HIDDEN #menu-project/#menu-ask (the menu
steps aside when a popover opens; closeProject never re-shows the handle),
passing without proving the visible hit path. Restructure: dismiss the open
popover, re-hover the cat to RE-REVEAL the menu, assert the next item is visible
AND hit-tested (__roroClickThrough.decideAt over its rect → true) AND that the
re-reveal doesn't wake the cat, THEN click it.

All eight touched smokes run live + PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35d23e6253

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// the hover-revealed Project popover (S4b), so those elements are present-but-hidden at rest. The floating
// pet's own surfaces are covered by the dedicated on-screen smokes (smoke-floating-*). Matches the
// sibling packaged UI smokes (model-setup, first-task).
env.RORO_FLOATING_WINDOW = '0';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep onboarding smoke on the default window path

When this smoke sets RORO_FLOATING_WINDOW=0, it opts out of the packaged mode a real first-run user gets; src/main/window.ts makes the unset/default value the floating pet, while this script is still the documented verify:packaged-onboarding gate for the no-env first-run banner/config flow. A regression that only breaks the default floating packaged onboarding path would now pass here because the test exercises the legacy framed #controls layout instead; consider running both modes or adapting these assertions to the default floating popover path.

Useful? React with 👍 / 👎.

gorajing and others added 6 commits July 4, 2026 06:10
Two doc-accuracy findings:
1. INTERACTION.md said 'Clicking a menu item IS a real interaction' — but only Ask
   summons+pokes (wakes the cat); Memory/Project are utility clicks that
   intentionally do NOT poke/pet/wake (the tests assert no poke). Clarified.
2. PRODUCT_PLAN.md listed 'right-click or M: mute/unmute' as current law, but v0
   default hides/absents mute (the onboarding smoke asserts Mute hidden; README
   narrows it to a voice dev flag). Gated the line as voice-dev-flag-only.

Docs-only; tsc/vitest/eslint unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nt app (codex S6 round 2)

Two more doc-accuracy findings — fitting for a truthfulness feature, the docs were
themselves over-claiming:
1. INTERACTION.md said the receipt shows when a fact 'demonstrably shaped the turn'.
   The gate actually attests RECALL (a same-run status with factCount>0 ||
   episodeCount>0, incl episode-only) — not proof a fact shaped the answer. Reworded
   to what the code verifies + an explicit 'never claims more than the pipeline can
   verify' note.
2. PRODUCT_PLAN.md still implied a voice-dev-flag-gated mute. window.ts:44 confirms
   there is NO RORO_*_VOICE reader in the app (voice extracted to packages/voice), so
   there is no mute UI/key path at all. Reframed the bullet accordingly.

Docs-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…codex S6 round 3)

Round-2 fixed one instance; codex found the same overclaim repeated in
INTERACTION.md (the truthfulness invariant bullet) + floating-redesign.md (founder
decision 5 + the S5 slice bullet). All now say the receipt attests same-run RECALL
(a status with factCount||episodeCount>0) attached to run.completed.finalText —
never that a fact provably shaped the answer. The only remaining 'shaped' is the
explicit negation ('NOT that a specific fact provably shaped the answer').

Docs-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…erclaims (codex S6 round 4)

Comment/doc-only accuracy sweep (the 'central change ripples widely' pattern, one
more layer):
- The 'recalled fact demonstrably shaped the turn' overclaim also lived in SOURCE
  comments (speechBubble.ts, bootstrap.ts, index.css) — synced to 'memory was
  actually recalled that turn (same-run status + run.completed.finalText)'.
- VERIFICATION.md + smoke-packaged-first-task called the framed dev window (which
  force RORO_FLOATING_WINDOW=0) the 'default typed surface' — but the default is
  FLOATING (window.ts). Reworded to 'framed dev typed surface'.
- VERIFICATION.md said the natural memory smoke 'does not launch floating-window
  mode' — it DOES (default); reworded to 'launches the default floating window,
  inspects receipt STATE via the hook, does not prove the visible render'.
- README mute line: no voice/mute path in the current app (voice extracted to
  packages/voice) — reframed like PRODUCT_PLAN.

Comment/doc-only; tsc/vitest/eslint unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fs (codex S6 round 5)

The central-UI change kept rippling into more docs + comments — codex found the
same stale refs across RUN.md, HANDOFF.md, PUBLIC.md, and bootstrap/runLifecycle
comments:
- 190x200 → 360x420 click-through (RUN, HANDOFF; kept the ACCURATE historical
  'old 190x200 window' / '190x200 cell' refs in avatar.ts/floatingLayout.ts/
  tether.test.ts untouched).
- 'compact Ask pill' / 'Stop pill on the cat body' → summoned input + tethered
  WorkingChip/Stop off-body (RUN, bootstrap:86, runLifecycle, the floatingAsk test
  name).
- 'the only turn surface = typed prompt' → typed input = dev prompt + floating Ask
  (bootstrap:10).
- 'default typed surface' → the framed dev surface (RORO_FLOATING_WINDOW=0)
  (PUBLIC.md).
- mute-as-interaction-law → mute lives in packages/voice, absent in the current app
  (RUN.md).

Comment/doc/test-name only; tsc/vitest/eslint unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…x S6 round 6)

- floating-redesign.md (the build spec) described the PLAN in spots the impl diverged
  from: WorkingChip verb 'activityForEvent' → the shipped reuse of summarizeEvent;
  'floatingAsk lifts into a DOM-free StageViews controller' → shipped simpler
  (mountFloatingAsk keeps its DOM shell + mounts stage islands, no controller needed);
  'delete #floating-ask/#floating-error' → they KEEP their ids but migrate onto the
  stage as tethered islands (only #ask-pill deleted; #floating-stop→#working-stop).
- RUN.md §5 Voice: the RORO_*_VOICE flags are not runnable from the root app (voice
  extracted to packages/voice; no app-side reader per window.ts) — added an
  'Extracted' note so the pipeline docs read as packages/voice, not root-app flags.

Docs-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gorajing
gorajing merged commit f183c72 into main Jul 4, 2026
3 checks passed
@gorajing
gorajing deleted the feat/floating-reconcile branch July 4, 2026 13:55
gorajing added a commit that referenced this pull request Jul 6, 2026
…gue fixtures, docs absorb the first dogfooding session (#162)

* fix(eval): repair the eval runners' post-W7 artifact paths + pin the path family in CI

Since the W7 core-split (#149) moved src/brain -> src/core/brain, both live
runners still wrote/read their artifacts under the stale 'src/brain/eval'
(runEval.ts latest/baseline writes; runProposalEval.ts baseline read +
proposalLatest/proposalBaseline writes) and crashed ENOENT at the end of a
full run. The directory now lives once in eval/paths.ts (EVAL_DIR +
evalArtifactPath), both runners use it, and paths.test.ts pins that EVAL_DIR
resolves to the directory the eval files actually live in (plus that the
checked-in baseline.json exists there) — sabotage-verified: reverting
EVAL_DIR to the stale path fails both tests. Also moves the two stale
.gitignore scratch entries (latest.json / proposalLatest.json) to the real
output location so runner scratch stays untracked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(eval): make deflect-on-vague measurable — 5 vague-initiative DECIDE fixtures (fixture-first)

First founder dogfooding session (2026-07-05): 'create something interesting'
made the 3B answer 'Let's brainstorm a fun project idea together' — a chat
deflection that fails ROADMAP §6's lands-or-clarifies bar (do the task or ask
a PERTINENT question). This adds the failure class to the eval WITHOUT
touching decide (measure first, fix later):

- DecideCase grows alsoAccept (a golden SET for lands-or-clarifies cases) +
  a 'vague-initiative' tag (the DECIDE-side analogue of BehavioralTaxonomy).
- 5 fixtures (vague-interesting/-cool/-fun/-buildme/-impress) accept exactly
  {run_agent, clarify}; answer FAILS. Expected to fail against the current
  model — that is the point.
- scoreDecision gains the optional alsoAccept set (red-first unit tests: a
  deflection still scores wrong_command).
- fixtures.test.ts pins the class deterministically in CI: acceptance set is
  exactly {run_agent, clarify}, and every vague case must NOT be caught by
  the deterministic clarify gate (same loud-re-label discipline as the
  marker-less pin), so the fixtures keep measuring the MODEL.

Live tier stays opt-in/report-only; the deterministic suites stay green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(eval): refresh the shape-stale baseline via --write-baseline (real Ollama, new fixtures included)

OLLAMA_AVAILABLE=1 npm run eval:brain -- --write-baseline against local
qwen2.5:3b — the sanctioned baseline workflow; baseline.json is never
hand-edited. The old snapshot predated the W3 5→50 fixture expansion and the
new runner output shape.

Old → new headline numbers:
- decide: 22/22 (100%) → 26/27 (96.3%; one wrong_command: run-writetest →
  answer — DECIDE streams at temperature 0.3, a run is a snapshot)
- extract: 10/10 (100%) → 10/10 (100%), unchanged
- behavioral value-quality: 2/5 (40%, the original 5-case set) → 26/35
  (74.3%, the full expanded set — reproduces the #145 report-only number)
- NEW keys now captured: behavioralNull 7/15 (46.7%; all 8 misses are
  hard-negative false_facts) + behavioralByTaxonomy (hard-negative 20% is
  the weak family; multi-fact/supersede/marker-less 100%)

MEASURED TRUTH on the new vague-initiative cases: contrary to expectation,
the current 3B lands-or-clarifies on all 5 (and 30/30 in a 3×-repeat probe
with and without a memory section) — the fixtures therefore PIN the class
against regression; the live 2026-07-05 deflection has not reproduced from
paraphrased transcripts, so the fixture-block comment now records that and
points the follow-up at promoting a RORO_TRACE capture of a real deflecting
turn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: absorb the dogfooding + floating/moat signal — LESSONS, HANDOFF, ROADMAP, VERIFICATION

- LESSONS.md: new Dogfooding entry (2026-07-05) naming the four failure
  classes — deflect-on-vague / feedback-fade / working-illegibility /
  env-overrides-config — each with its file:line locus and fix status
  (2–4: the sibling dogfood-blocker slice; deflect-on-vague:
  fixture-first, with the measured 2026-07-06 twist that the paraphrased
  fixtures currently PASS, so the real repro needs a RORO_TRACE capture).
- HANDOFF.md: §3 work log extended past W8 — the floating redesign
  (#153#160, resting purity + truthful receipt), earn-the-moat (#161,
  codex finalText stitch + verify:memory-steered-real 5/5 vs 0/5), the
  first dogfooding session, and this signal-reconcile slice; §4 gains the
  refreshed-baseline numbers (the old bullets stay as the historical
  snapshot); §8 gains the corrected forward order (dogfood fixes →
  signing → legible-moment → executor-facts pilot → self-rehearsal →
  demo → stranger session).
- docs/ROADMAP.md: Arc A §6 step 5 (founder dogfooding) marked STARTED
  2026-07-05 with the four findings + the fixture-covered status of
  deflect-on-vague.
- docs/VERIFICATION.md: the stale pre-W7 layout references in the cohort
  trace-review section (lines ~10–27) now point at src/core/… (the vitest
  command there was unrunnable). Stale paths in LATER sections of the file
  remain — out of this slice's scope, flagged in the handoff report.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(review): address the review panel — doc truthfulness + pin hardening (S-A round 1)

Panel findings (all CONFIRMED, 0 false positives across the 5-hat review):
- BLOCKER: four docs-of-record sites claimed feedback-fade was 'being fixed in the sibling
  dogfood-blocker slice' — it is NOT (it belongs to the upcoming legible-moment slice). LESSONS,
  HANDOFF x2, ROADMAP now say so honestly, and working-illegibility is split truthfully
  (sleep-mid-run half → dogfood-blockers; the distinct working pose → legible-moment).
- LESSONS locus corrected: summoning the ask also pokes the presence clock, not only petting.
- alsoAccept untag loophole closed: any DECIDE case widening its acceptance set must declare a
  failure-class tag (pinned in fixtures.test.ts) — an untagged alsoAccept was silent softening.
- evalArtifactPath now __dirname-based (correct from ANY cwd, travels with the dir on a move);
  new source-grep pin: the runners must route through evalArtifactPath, no quoted hand-spelled
  eval dirs (the exact post-W7 breakage class), header-comment convention exempted.
- Stale src/brain path sweep: cohortTraceReview.ts fixture pointer, COHORT_TRACE_TO_EVAL.md
  verify command, RUN.md:20, README.md x2, WS1 doc x2, ROADMAP live locus.

tsc clean · 1104 passed / 12 skipped · eslint 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: sweep stale PGlite/pgvector memory claims + the temp-0 eval claim (codex S-A round 1)

Codex caught materially-false user-facing docs surviving the reconcile: README (6 sites) and
RUN.md (4 sites) still described memory as an in-process PGlite+pgvector database at src/memory2 —
deleted in W5 (#147); memory is encrypted files-as-truth + a rebuilt-on-launch in-memory vector
index at src/core/memory2, embeddings via local nomic-embed-text. Also HANDOFF's eval header said
'temp 0' while decide actually streams at temperature 0.3 (brain/index.ts:190) — the same header the
new baseline note's temp-0.3 explanation contradicted. And the crosslaunch proof pointer moved to
src/core/orchestrator/. All claims now match the code.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: complete the pre-core-split path sweep + fix dangerous embedder advice (codex S-A round 2)

- RUN.md's embedder note was DANGEROUS post-W5: it described a fixed vector(N) DB column and told
  users to move/delete the memory dir when changing embedders — that dir now holds the durable
  encrypted memories (files-as-truth); vectors.jsonl is the zero-authority derived cache that
  re-embeds automatically. Rewrote to the true architecture.
- README executor pointers (table + tree) → src/core/executor/.
- VERIFICATION.md: ALL remaining pre-core-split paths fixed (memory2/executor/orchestrator test
  commands + module pointers); ROADMAP tracer pointer; PHASE2-TRUST-LOOP's runbook command fixed
  (adapter.test.ts was deleted in W5 — removed) and PROVEN to resolve (34 tests).
- Exhaustive residual sweep across *.md + docs/: zero non-historical pre-split paths remain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: exists-checked path sweep — src/main→core/orchestrator (codex S-A round 3)

Round-3 findings + a proactive exists-check sweep: ROADMAP's configStore/memoryContext pointers,
the eval fixtures/score header comments, and 12 stale src/main/<file> references across the md
corpus (all moved to src/core/orchestrator in W7) — now verified by an automated
every-md-path-must-exist check returning zero stale refs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: last stragglers — PHASE2 adapter-successor pointer + eval-source comment paths (codex S-A round 4)

PHASE2-TRUST-LOOP prose now names facade.test.ts as the successor to the W5-deleted
adapter.test.ts; every src/brain|src/executor comment path inside src/core/brain/eval/*
swept to core (grep-verified zero non-core refs remain).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: two path stragglers that escaped the exists-check shapes (codex S-A round 5)

PHASE2's relative memory2/profileFacts pointer (no src/ prefix) and VERIFICATION's
src/main/memoryHealth* wildcard — both shapes now covered in the sweep; ROADMAP's relative
brain/index.ts ref fixed alongside. src/main/ipc*.test.ts verified VALID (ipc tests do live in
src/main).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: precise privacy claim — the index is derived/plaintext, the FILES are encrypted (codex S-A round 6)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: embedder-switch remedy is delete-derived-index-only, not auto-re-embed (codex S-A round 7)

vectorCache.ts:20 IDENTITY REFUSAL: a mismatched (embedModel, dim) header THROWS; the store does
not silently re-embed. Remedy: delete the derived index/ subdir (zero-authority; next launch
re-embeds from the durable encrypted files). My round-2 rewrite overstated the automation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

* docs: the PHASE2 gate command now runs facade.test.ts, matching its own prose (codex S-A round 8 — cap)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vsq543S6voPTUsGsEqZvnD

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant