- Rewrite the 08-04 gutter-reservation note in place: the reservation is Chat's alone and the overlay branch points to the seat-width compensation note; the Testing section now describes the uncompensated control.
- Cross-reference the earlier rejection of the seat inset in the 08-12 note and record the engine-resolved-vs-fixed-8px drift as accepted residual cost instead of asserting Firefox resolves 8px.
- Pair --dsh-scrollbar-width with the mirrored ::-webkit-scrollbar rule and the compensation consumer in the scrollbar-styles gate; document the variable in the ui-theme README.
- Rename the e2e control to compareTabsWithoutCompensation and correct the vacuity-guard comment; rewrap the WorkspaceBrowser doc comment.
- stateVersion starts at 1: the package is new, no persisted rows predate it
- pendingCalls pairs by own key so a provider callId naming a prototype
property cannot fold toolMs to NaN on an unmatched crash-recovery result
- StatsLine folds the window fallback only when no sessionStats value is
served, and gates the token group on actual token activity instead of
steps, so failed-only sessions drop the zero-token group
- correct the crash-step counting semantics in the README and Agent Note:
recovery closes interrupted steps with a synthetic step/end on reload
- reword the window-scoped alternative as a plain rejected option and name
isTokenDelta's home beside the StreamChunk type
Card registration order is stable only for cards one package installs
together: apply order between packages is unconstrained, so several
external cards can still reorder between boots. The note and README said
otherwise. Recorded alongside it: the redactor returns a secret reachable
only through a union, intersection, or transform verbatim, and serving
every registered namespace widens that gap to third-party schemas; and
the headline capability still lacks an assembled-composition test.
publish() now keeps its snapshot reference when neither the loaded flag
nor the dispatched namespaces moved, so an unrelated settings commit no
longer re-renders the card list.
The Agent Note claimed the plugin inventory page already exposed every
mounted plugin's effective configuration to the same browser, so the
removed allowlist blocked nothing a caller could not already read. That
is false: PluginInventoryEntry carries entryId, moduleName, enabled, and
fiberPhase, and the page's configuration row renders an enabled tag, not
a stored value. The allowlist did keep an unlisted namespace's resolved,
base, and user values off the wire; the note now says so and rests the
decision on the loopback pin, secret redaction, the user's own document,
and the fact that permission and agent-presets were already served.
The post-await disposal check reads through an opaque method, mirroring
the settings seam's isStopped(): control flow narrowed the field to false
across the await, so the lint gate saw the guard as dead.
The per-file coverage gate flagged four uncovered locations the new
section directory introduced: refresh() after disposal, a read superseded
by a newer one, and the two invalidation handlers that make the served
namespaces re-read (settings/document-updated and connection/reset).
A plugin that registered a settings namespace could not reach the browser
configuration page: the api-proxy filtered every read and gated every
write through two hardcoded namespace lists, and the plugin configuration
section rendered an unordered list of cards carrying an opaque id rather
than the namespace they edit. Both gates lived in this repository, so a
user-authored plugin was configurable only by hand-editing settings.yaml.
The proxy now serves whatever ctx.settings.describe() returns and adds no
boundary of its own; a name no registration answers folds into the seam's
own settings-rejected, and the settings-not-exposed code retires. The
settings seam is untouched: which client may read a namespace, and which
page renders it, are facts about consumers.
settings.plugin.item becomes a keyed slot whose key is the namespace a
card edits, following tool.call.toolview. The section reads describe once
and dispatches the intersection of the slot ledger and the served set, so
a namespace another surface owns renders nothing without declaring
anything, and a card for an uncomposed plugin is never dispatched.
Keep both Remote contributions master and this branch add: the mount loop
now carries commandsRemote, goalsRemote, pluginInventoryRemote, and
messageFeedbackRemote, with both new tsconfig references retained.
Anchor the max-tokens notice between the closing assistant and the
turn-tail so the tail stays the turn's last chat node and its branch
action survives; forward the ChatNodeDataMap augmentation through the
client entry so built declarations publish the new kind; advance the
fixture's nextTurn past the appended history; drop the engine-unreachable
buildViewNode fallback; deduplicate the runtime README tail sentence.
A turn the provider ends at its per-request output cap previously produced
no visible sign in the Web chat flow: only error-kind turn/end events built
a conversation node, so the truncated answer read as a normal completion.
Add a turn-max-tokens conversation node Definition over the durable
turn/end event, a warning-styled localized notice row distinct from
turn-error, a fixture max-tokens sample turn, and an assembled keyless
snapshot pinning the dot state, title, and hint.
Closes#1522