- Keep ConversationSession mounted for blank sessions (chrome-less) so the
draft-persistence mirror stays bound in the hero; hero typing reaches the
chat store again.
- Restore the baselines-ready gate in AppFrame: empty boot snapshots no
longer flash the New Workspace hero before either baseline lands.
- Commit ordinary sends through the machine (send-committed event +
Shell.commitSend): undo can no longer resurrect already-sent content on
the default-sink path.
- Give the production InputMachine a real wall clock so the typing-run
merge window actually expires.
- Coalesce concurrent connectWorkspace creates per workspace: the summary
has no cwd until the host frame lands, so a second New Session inside
that window minted a duplicate hidden blank session.
Same client-lane debt as the existing GUI exclusions (TODO(gui)): the new
ui-slash/ui-command/ui-skill/ui-sidebar/ui-workspace client files and the
connection fixture keep their uncovered branches until the browser-grade
harness lands.
Test-side catch-up with the session-maybe conversation architecture: the
provide channel's descriptor shape and maybeProvideInfo in fakes, the shared
chat-store handle asserted on conversation.session (the session-maybe shell
carries no store), startSession fakes exposing the workspace list snapshot,
strict session slots declining (not throwing) without a session, AppFrame's
removed empty seat and loading gate, and the hero draft asserted on the
machine (the chat-store mirror binds with ConversationSession). Plus three
lint fixes (max-len split, boolean-compare, arrow-parens/unbound-method).
eslint --fix autofixes plus manual repairs: max-len line splits
(fake-api handlers, notifier/slots JSDoc, spec signatures), charAt over
non-null-asserted indexing in slash detect/menu cores, Array.from for
code-point capping, typeof assertions for unbound-method in specs,
generic getByRole for the send-button cast, effect disposer void-wrap in
command register, and dropped unused type imports.
Head-to-head replay of the same ten historical examples, both arms in
one time window with identical prompts and pairwise blind judging:
prose quality and cost at parity (stylistic margins only); the shipped
briefing wins two objective outcomes — code-fence-only examples land
byte-identical to the human-reviewed updates with zero model tokens,
and the flagged first-occurrence move reproduces the human-reviewed
gloss relocation the section-only form leaves as a contract violation.
Chinese counterpart brought along via the briefed path and the pair
re-recorded.
The briefing now maps each update at the narrowest safely aligned
granularity, widening deterministically on mapping failure: a change
confined to the pair's byte-identical code fences is computed outright
(--apply splices it into the counterpart and validates the result
against the pairing gate's structural signature before writing);
otherwise changed Markdown units — headings, paragraphs, table rows,
list items, fences, block quotes, HTML blocks, thematic breaks, link
definitions, matched by container-scoped kind sequences — each carry
their last-confirmed source, current source, and current counterpart
text; units that do not align fall back to depth-matched heading
sections (depth only, so translated heading text still maps); and when
sections do not align either, or both sides drifted, the briefing says
so and withholds the mapping. Terminology rows now match the changed
spans only, English terms on word boundaries with plural inflections,
and Chinese-target briefings track each relevant term's document-wide
first occurrence — a moved occurrence pulls the vacated and receiving
spans into the briefing with an explanatory note.
The unit mapping, mechanical code splice, and first-occurrence tracking
adopt the planner design from the incremental prompt-pipeline PR (#684),
whose provider-backed bake-off independently validated the same scope
ladder; this PR carries those mechanics into the agent-facing briefing
path so both consumers of the consistency records behave alike. The
prior line-hunk section mapping and its heading-text alignment (which
could not map cross-language sections) are replaced wholesale.
Docs: SKILL.md update path, i18n README pair, development.md pair, and
the briefed-updates Agent Note pair brought along; the development.md
fence edit was applied with --apply itself, and the prose updates were
made through the new unit/section briefings.
The dsh-translate-docs skill now triages updates onto a briefing-driven
path — gen-translation-brief output as the translator's whole working
set, orchestrator-applied mechanical fence edits, scoped record/check —
while the whole-document path for new pairs is unchanged. The i18n
README documents the scoped gate forms and the briefing tool;
development.md lists the new command; the new bilingual Agent Note
records the decision and the ten-example benchmark behind it (briefed
path ~1/3 the tokens and wall clock of the corpus-loading path at equal
judged quality; whole-document re-translation rejected on preservation
collapse). Counterpart updates in this commit were produced with the
new briefed path; the new note's Chinese side is a whole-document
translation.
gen-translation-brief assembles the minimal-update working set for an
out-of-sync pair from its consistency record: the authored side's diff
since last confirmation, the counterpart sections that diff lands in
(heading-mapped only where the last-confirmed structures align), the
terminology rows the diff touches, and a per-direction rules digest.
verify-translation-pairing now accepts pair paths to check just the
named pairs during update iteration; --write requires naming the
confirmed pairs (--write --all is the explicit corpus form) so a bulk
re-record can no longer silently bless drifted pairs the caller never
reviewed. Each record's comment names its own scoped command.
PR #679 implemented the swap and falsified the note's parity premise:
vitest's fake clock does not intercept node:timers/promises, so the
change traded deterministic fast tests (llm-retry ~4s->~10s real
sleeps, two pty teardown tests rewritten real-time, a weakened
workflow grace-timer guard) for ~10 deleted lines. Moved the note
proposed -> rejected with the verdict on the Status line; the frozen
proposal body is kept per the rejected-lifecycle contract.
Every PR that changes product-user-visible GUI behavior now includes a
demonstration GIF with real provenance (that branch's built tree, real
key, real model rounds). Recording stays side-effect-free; the skill
gains a bounded final publication step: GIFs go on an append-only
orphan assets branch (one per PR series) and embed via the blob URL
with ?raw=true, never on the PR branch itself.
Folds in the operational lessons from the Code Mode UI series:
.playwright-mcp/ screenshot roots (now gitignored), per-PR staging and
precise server teardown, one-call DOM polling for transient states,
exact-text completion predicates, prompt engineering for UI states,
and the export-before-invoke GIF_SKILL_DIR encoder pitfall.
Agent Note: implemented/process/2026-07-26-gui-pr-gif-evidence-and-assets-branch (+ zh pair); the 2026-07-23 recording note now defers publication policy to it.