Skip to content

Commit 5fa7f62

Browse files
authored
Merge pull request #58 from harmoniqs/kate/chat-brain-background
docs(amicode): ADR 0002 — the Brain becomes the Chat's living background
2 parents 18b9452 + d2cb625 commit 5fa7f62

2 files changed

Lines changed: 143 additions & 0 deletions

File tree

‎packages/app/CONTEXT.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ other surface opens beside or in front of the Chat; the Chat is never replaced b
2222
another surface, only overlaid. There is no view in which the Chat is absent.
2323
_Avoid_: Main view, editor, session pane (as the whole hub)
2424

25+
**Brain**:
26+
The data-true living background of the **Chat** — a map of the current session's thought that
27+
fills the Chat behind every component and is never interactive. One per window, present wherever
28+
the Chat is (Landing included) and nowhere else.
29+
_Avoid_: Background, wallpaper, atmosphere, brain strip, canvas
30+
31+
**Glass**:
32+
The frosted, translucent surface every chat component floats on above the **Brain** — tinted
33+
just enough that text stays legible over the moving graph. (How the blur and tint are derived
34+
is an ADR-0002 concern, not a glossary one.)
35+
_Avoid_: Card background, frosted panel, blur layer, tier
36+
2537
**Rail**:
2638
The one narrow vertical strip of icons along the window's leading edge. Collapsed to
2739
icons by default; each icon reveals its text label on hover. The Rail is the only
@@ -68,6 +80,9 @@ only surfaces its state), setup wall
6880
## Relationships
6981

7082
- The **Landing** is a **Chat**; the window never opens on anything else.
83+
- The **Brain** is the background of the **Chat** and only the Chat; every chat component
84+
floats on **Glass** above it, while the **Rail**, titlebar, and **Panels** stay solid and
85+
frame the living pane.
7186
- Every **Rail surface** opens as a **Panel** beside the **Chat**; the Chat is never
7287
replaced, only overlaid, and at most one Panel is open at a time.
7388
- The **Rail** carries navigation surfaces above and the **Account zone** below; both
@@ -100,3 +115,6 @@ reader meeting them in older code or notes should map them forward:
100115
a possible future, not part of this redesign. See ADR 0001.
101116
- **Home cards** "Meet Amico" and "Jump back in" → folded into the first-run Landing and
102117
the Chats surface respectively; they are no longer standalone surfaces.
118+
- **Inline brain strip** (the Brain as a single row inside the message timeline) → absorbed
119+
into the **Brain** background. One render loop, promoted from a timeline row to the room;
120+
the timeline keeps only its text shimmer. See ADR 0002.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# 0002 — The Brain becomes the Chat's living background; components float on legibility-floored glass
2+
3+
- Status: Proposed
4+
- Date: 2026-07-24
5+
- Deciders: Kate Bonner (Head of Product)
6+
- Tracking: harmoniqs/opencode#56
7+
8+
## Context
9+
10+
The amico **Brain** — the data-true, live map of a session's thought — currently renders
11+
as an inline strip *inside* the message timeline (a native canvas engine; the `/brain.html`
12+
iframe was already retired). It is one row among many, easy to scroll past, and it competes
13+
with the messages rather than framing them.
14+
15+
An earlier redesign (`kate/chat-brain-atmosphere`, six commits, never pushed or merged)
16+
explored promoting the Brain to a chat-wide background behind *tiered per-bubble glass*
17+
("atmosphere"), reaching a resolved design and a Phase-5 build. Kate reopened the design
18+
fresh rather than continuing that branch. The open question: does the Brain stay an inline
19+
timeline element, or become the **permanent background of the Chat** with every component
20+
floating on frosted glass — and if so, how is legibility *guaranteed* when text sits on a
21+
translucent surface over a moving graph? "Movement comes through" (translucency) and
22+
"highly legible" (contrast) are in direct tension, and the earlier build hit exactly one
23+
legibility failure: muted grey text not clearing WCAG-AA on its most translucent tier.
24+
25+
This decision governs the **Amicode app UI** (the opencode fork). It sits under ADR 0001
26+
(chat-first shell): the Chat is the one persistent hub, and this ADR settles what the Chat
27+
*looks like*.
28+
29+
## Decision
30+
31+
**The Brain becomes the permanent, full-bleed background of the Chat** — Landing,
32+
conversation, and composer all sit on it. There is **one Brain**: the inline timeline strip
33+
is absorbed into the background (one render loop, promoted from a timeline row to the room).
34+
The **Rail, titlebar, and Panels stay solid**, framing the living pane. The Brain is a fixed,
35+
viewport-anchored backdrop; cards scroll over a stationary Brain.
36+
37+
**Every chat component floats as a frosted-glass card, and legibility is guaranteed by
38+
construction — not by eye:**
39+
40+
- **Blur** — a *high, constant* gaussian blur on every card. It provides perceptual calm and
41+
kills the high-frequency motion detail that hurts reading. It is cheap (no per-frame logic)
42+
and it is *not* what makes text legible.
43+
- **Tint** — contrast comes entirely from a tint whose **opacity is pinned to clear the WCAG-AA
44+
floor (with a small safety margin, not exactly at the floor) over a fixed reference frame** —
45+
a synthetic Brain at peak bloom in which the sampled backdrop is the brightest palette value
46+
**the Brain actually paints in that theme** (peak `#fff676` on dark; peak `#8f8000` on light —
47+
the light-mode Brain never paints `#fff676`, so validating against it there would derive a
48+
near-transparent tint that silently fails over the real light frame). Blur smooths the backdrop but does not darken it; a card over a bright-yellow
49+
cluster is still on bright yellow until the tint pulls the composite toward the ink. The tint
50+
set is **keyed to the chat's own theme** — the chat runs a theme independent of the app shell
51+
(default oc-2) — so a chat-theme change re-keys the Glass and re-validates contrast. **Two
52+
tints:** *standard* (prose, bubbles, composer) holds body text ≥4.5:1; *dense* (code, diffs,
53+
run-plots) is more opaque and holds code/diff text ≥4.5:1 and graphical marks — syntax colors,
54+
diff fills, plot lines — ≥3:1 (WCAG 1.4.11), so colored content stays crisp.
55+
56+
**The Brain is data-true with an adaptive heartbeat.** Nodes light up as amico reads files,
57+
runs tools, and touches the vault; the graph grows with the conversation, **densifying in place
58+
within the fixed, viewport-anchored frame** — bounded by a node cap / recency window so a long
59+
session neither scrolls the Brain nor grows its per-frame cost without limit. Motion follows
60+
activity: a lively tempo when amico is working, ~8fps breathing at rest, and a **hard pause**
61+
when the window is hidden or `prefers-reduced-motion` is set. At rest it shows a **sparse
62+
seed** — a near-empty Landing whose graph grows *only* from the current session's real
63+
thought, with **no cross-session persistence** (a fresh session opens nearly empty). One Brain
64+
per window shows the **active** session; switching the titlebar session tab swaps the Brain to
65+
that session's graph.
66+
67+
**Pre-agreed perf fallback (non-negotiable mid-build):** the frosted look is protected. At
68+
rest, full blur and full motion always apply. A frame-time monitor trips the ease when p95
69+
frame time stays over budget for a sustained window (with hysteresis before restoring, to
70+
avoid oscillation): the Brain's *motion* eases (calm/slow) and returns to full tempo at rest.
71+
If easing motion to a full stop still misses budget, the Brain **hard-pauses to a static
72+
blurred field** — the terminal valve — but **blur fidelity never degrades.**
73+
74+
**Build by reuse.** A new, well-named branch off `local/amicode` reuses the de-risked native
75+
plumbing — the native Brain engine, the glass-token generator, and the mount wiring from the
76+
earlier branch (design-neutral, already hardened by an adversarial port-fidelity review) — and
77+
builds the *design* layer fresh. No iframe. Both light and dark themes are first-class from day
78+
one.
79+
80+
See `packages/app/CONTEXT.md` for the new vocabulary (**Brain**, **Glass**).
81+
82+
## Consequences
83+
84+
- The **inline brain strip** is retired as a timeline row; the timeline keeps only its text
85+
shimmer (the existing working indicator — the cycling gerund + live elapsed shown while a turn
86+
works). One Brain, one render loop.
87+
- **No node-level interactivity is lost.** The strip's only affordance was a click-to-expand/
88+
collapse toggle (it was a collapsible row); the Brain engine has no node hit-testing. As an
89+
always-present background the expand toggle is obviated, not removed from a capable surface.
90+
- When a solid **Panel** covers the Chat, the Brain need not animate behind the occluded area —
91+
a cheap perf saving, since Panels are opaque.
92+
- The *standard* tint's opacity is **bounded below** by the contrast floor — it cannot be made
93+
ultra-transparent, or muted grey text fails AA over the reference frame (the exact
94+
failure the earlier build hit). Secondary/muted text therefore rides the *dense* tint or a
95+
locally-dimmed zone.
96+
- The Chat's cost profile changes: high-radius backdrop-blur recomputed per frame over an
97+
animating canvas, across many cards, while scrolling, is the expensive combination. It must
98+
pass a **laptop-webview 60fps gate** (the real target — headless Chromium is only a proxy);
99+
the motion-ease fallback is the release valve.
100+
- The **Rail, titlebar, and Panels are deliberately excluded.** Nav chrome stays rock-solid,
101+
and dense Panel lists (Chats history, Run gallery) don't fight a moving background.
102+
- The Landing (a fresh, empty Chat per ADR 0001) now opens on the sparse-seed Brain rather
103+
than a blank surface — the window's first impression is the living background, calm and
104+
nearly empty, not a widget wall.
105+
106+
## Alternatives considered
107+
108+
- **Keep the inline brain strip** (a timeline row). Rejected: it is one element among many;
109+
the redesign's intent is the Brain as the room, not a row.
110+
- **One calm reading lane / unified glass sheet** (Brain only in the margins). Rejected in
111+
favor of per-component floating cards — motion lives in the gaps between cards, which is
112+
where "movement comes through" *without* the cards themselves having to be see-through to it.
113+
- **Dynamic contrast glass** (each card samples its backdrop per frame and adapts its tint).
114+
Rejected: per-frame readback is the biggest perf risk and AA is hard to prove against every
115+
frame; the static AA-floor tint is deterministic and cheap.
116+
- **Quiet zone behind cards** (dim/slow the Brain under each card's footprint via per-card
117+
masking). Rejected: real engine complexity for translucency the gaps already provide.
118+
- **Breathing skeleton atlas at rest** (the full latent graph, dim, breathing). Rejected in
119+
favor of the sparse seed — calmer, more literal, and it lets the floating cards dominate.
120+
- **Protect motion and ease blur under load**, or **degrade only while scrolling**. Rejected:
121+
the frosted look is the aesthetic being protected; motion is the acceptable give under load.
122+
- **Rebuild the engine clean**, or **evolve the old `kate/chat-brain-atmosphere` branch**.
123+
Rejected: reuse the de-risked plumbing (including its already-fixed port defects), but build
124+
the design fresh on a new branch rather than inherit the old design structure or re-pay for
125+
the engine port.

0 commit comments

Comments
 (0)