Master had advanced 392 commits. Every conflict was a derived artifact both
sides had regenerated — `docs/tool-catalog.md`, four recorded headless
session logs, and one TUI terminal expectation — so each was resolved by
taking master's version and re-running the generator and the keyless
snapshot refresh on the merged tree. No source file conflicted.
The new `examples/jsonrpc-agent` fixtures keep master's scrubbed
`{{system}}` / `{{tools}}` headers: that suite scrubs request headers, so a
new tool changes nothing there and the refresh output was discarded.
`ConnectionHandle.sessionSearchResultLimit` mirrored
`SESSION_SEARCH_RESULT_LIMIT` as per-connection state, giving one fact two
homes in the same module and implying a transport-varying or server-negotiated
bound that the response schema's fixed `max` forbids. `SessionsService` now
reads the constant directly and its constructor drops the parameter; the
connection handle and its unreachable `/client` value re-export go away.
The import comes from the inline-safe wire layer rather than the connection
plugin's `/client` surface, which the bundle-purity gate rejects for value
imports.
The review made every name a JSON string with `<`, `>`, and `&` escaped. The
hazards behind that are real and each is now covered: a control character
splits one entry across lines, `</` closes the envelope, and a regular file
named `x@` reads as a socket named `x` under the non-regular marker.
Quote those, and only those. `list` is the tool an agent reaches for first
and its output sits in every transcript, so `"archive"/` on every ordinary
line is a permanent cost for a case that almost never occurs. A name is now
emitted verbatim unless it matches a control character, a leading quote, a
backslash, `</`, or a trailing `@`, and is otherwise a JSON string with `</`
neutralized — the delimiter treatment `dsh-workspace-context` already applies
to instruction text, extended to an interpolated path as its
`instruction-frame-paths` TODO asks.
Registrant-private reactive facts previously reached components as raw
observables that each component subscribed by hand (InputBar notices/
lexicon via uSES, SettingsRoot via a version/subscribe/getter triple).
The inject face now carries a reserved hooks compartment of bare
sources; the renderer binds each into a use<Name> selector hook through
the same machinery as the provide channel, so components consume
useNotices/useLexicon/useSections and never see a subscription
primitive. InputBar and SettingsRoot are the first two consumers.
Verifying browser-visible plugin CSS needs a rebuild build:web does not
perform: WorkspaceBrowser.module.css never reaches apps/web/dist, because
ui-workspace loads as a runtime plugin with its CSS inlined into
lib/client.js by that package's own bundle script. A negative control that
reruns only build:web exercises a stale bundle and passes with the
declaration removed, which reads as a vacuous test rather than an invalid
control. No script in the web lane does this rebuild, so every scroll-region
or plugin-CSS change hits the same trap.
Agent Note for the two changes: what the session log showed, what ordering
can and cannot fix (measured, correcting the first diagnosis), why the page
is sampled only past the cap, why `list` is needed alongside it, and the
alternatives each one beat.
design-platform.css declared four --dsw-alias-scrollbar-* tokens in both
palettes that no rule read, so every scrolling region rendered the user
agent's own scrollbar and the dark theme showed a light native bar against
dark surfaces.
The symptom that surfaced the gap was in the sidebar: the workspace
browser's session list is its only scrolling region, and each row's
trailing content (the relative timestamp, and the hover action buttons
that replace it) is `flex: none` flush against the row's 8px right
padding, so an overlaid scrollbar painted on top of the timestamp.
ui-theme/styles/scrollbar.css becomes the sole consumer of the four
tokens, imported by the web shell's base.css after design-platform.css
because it reads that sheet's tokens. The rules sit on `body`, not
`html`: the alias tokens are declared on `body`, custom properties
inherit only downward, and from `html` they resolve to the
guaranteed-invalid value with scrollbar-color computing to `auto`.
scrollbar-width and scrollbar-color are declared on `body, body *` rather
than inherited, because inheritance would carry the color already
substituted at `body` and an elevated surface could not retint its own
thumb; scrollbar-width does not inherit at all.
Both the standard properties and the ::-webkit-scrollbar pseudo-elements
read one indirection pair bound to the l1 tokens, so an elevated surface
rebinds that pair to the l2 tokens once and retints both renderings. The
command popup, slash menu, model-select panel, and settings panel do so,
which gives the l2 tokens their first consumers.
WorkspaceBrowser's `.list` declares scrollbar-gutter: stable, keeping the
bar beside the rows. `stable` rather than `auto` so the reservation holds
when the list is short enough not to scroll: expanding a workspace group
would otherwise shift every row sideways at the moment it starts
scrolling.
The rebase onto master picked up #585 (agent-loop message machine), which
removed the request-only session-prefix seam; the unified sourced-message
decision now owns the mechanism and the note's own banner declares the
seam removed. Archive the triplet and rewrite the skill-system note's
catalog mechanism against the shipped agent/step sourced injection,
keeping the archived note as the intentional historical citation.
Re-checked the other notes master added or amended (provider retry
policies, request-error retry action, observable state machine, OTel
telemetry, dependabot): their supersessions were already executed
upstream in the same PRs; no further active note qualifies.