L55 said 'An additional serial Linux reference runs ...', but L53 already lists the
self-hosted serial Linux standby as the existing reference, so 'additional'
implied a second one. Reword to 'The self-hosted serial Linux reference runs ...'
and mirror in zh L55. Re-record the i18n hash.
Per review: the self-hosted serial standby is not portable evidence — portable
means standard GitHub-hosted capacity without repository-external runner
configuration, which the self-hosted vm-backup/dsh-win-ci pools do not satisfy.
In 2026-07-22-evidence-based-larger-hosted-runners L73, distinguish the two:
standard-hosted compatibility jobs preserve portable evidence, while the
self-hosted serial standby preserves complete-aggregate evidence. Update the en
and zh pair and re-record the i18n hash.
Keep the remaining current-state Agent Notes in line with removing the hosted
serial-linux job (PR #2744), per the implemented-note rule that mechanisms stay
current in the same change that alters them:
- 2026-07-30-web-browser-snapshot-ci-gate (L15/L21): the hosted default-branch
Linux serial job no longer produces the browser cache; pull requests restore
the archived cache without a master producer, and only the self-hosted standby
runs the comparison on master.
- 2026-07-24-web-gui-browser-e2e-lane (L49): no hosted Linux serial producer of
the browser cache remains; the self-hosted standby runs the same gate.
- 2026-07-23-portable-required-pull-request-ci (L19): the serial completeness
check is now provided by the self-hosted vm-backup/dsh-win-ci standby lanes,
with serial-macos as the only disabled hosted serial.
- 2026-07-22-evidence-based-larger-hosted-runners (L17/L53/L73): serial
completeness evidence comes from the self-hosted standby pools; no hosted
Linux serial reference remains.
All four en/zh pairs updated with consistent current-state wording (no deletion
narrative) and i18n hashes re-recorded; note-format still passes.
Address the review findings from the fresh pass on PR #2744:
- 2026-07-21 note L31: the enabled serial references run on the self-hosted
vm-backup/dsh-win-ci pools and the only remaining disabled hosted serial is
serial-macos (macos-latest); removed the stale hosted ubuntu-latest/windows-2025
serial framing and the outdated 'when enabled, serial / windows' clause.
- Drop remaining change-narrative from both notes: L19 (serial / linux, macos)
and the 2026-07-26 caching note L16/L34 now state only current facts without
deletion dates/PR numbers; the no-producer fact has one home (L16). zh.ms'
'直至其过期为逐出' corrected to '直至其被逐出'. Bilingual hashes re-recorded.
- ci.yml TODO notes that re-enabling serial-macos does not restore a Linux
hosted-cache producer and records the seeder-vs-remove decision direction.
- The Playwright restore's failover-skip comment is now self-contained (the
VM's persistent browser cache is warm) instead of pointing at the coveragelane
rationale, which is pnpm-store-specific.
Verification: scripts/ci-workflow.spec.ts passes (12/12), YAML re-parses,
both translation pairs consistent, git diff --check clean.
Apply review feedback on the serial-linux removal (PR #2744):
ci.yml:
- Rewrite the new comments as current-state statements, not change
narrative (dsh-prose-standard): the TODO names serial-macos as the one
remaining disabled hosted serial job; serial-macos's intro and the
self-hosted standby's frozen-archive note no longer narrate the deletion.
- The self-hosted standby's frozen-archive comment states its own reason
(full history to resolve DSH_ARCHIVE_BASE_REF against github.event.before)
instead of referenceing a now-nonexistent hosted serial reference.
- Move the hosted-cache comment above the pnpm restore so it covers both
restore-keys fallback steps, and describe the real consequence (matches the
archived entry until evict, then cold) instead of the false
'cold on a lockfile change'. Restore the per-step failover-skip note.
Agent Note 2026-07-26-pnpm-action-setup-for-symmetric-ci-caching:
- Update the restore-only bullet and the consequences closing line (it
described serial-linux as the active master-push producer of the pnpm store
cache) to state that no master job produces these hosted keys since the
producer was removed; the Problem and Alternatives sections are historical
context and are left unchanged. Re-record the bilingual pair hashes.
Verification: scripts/ci-workflow.spec.ts passes (12/12), YAML re-parses,
both translation pairs consistent, git diff --check clean.
- Translate the zh Agent Note's title and section headings and align
its rail terminology with the established zh READMEs (轨道).
- Disambiguate 'the browser's listener' to WorkspaceBrowser's in the
English note.
- Record the in-flight outside-click exception in the ui-workspace
README (both languages) and the owning workspace-sidebar feature
note, cross-linked to the bug-fix note.
- Add an apps/web real-browser scenario pinning the document-level
bubble the jsdom test cannot replay: one real rail click must leave
the search expanded and focused, and a genuine outside click must
dismiss it afterwards. Negative-controlled against the unguarded
code (fails in 12s on the aria-expanded assertion).
- Register the new e2e file in the host tsconfig face and the client
face's exclude list.
The rail search click flips the shell wide and mounts the outside-click
dismissal listener during its own dispatch; the click then bubbles to
document with the unmounted rail button as its target — outside
searchRoot — so the listener dismissed the search it just opened. The
listener now stays off while the rail gesture is in flight
(searchOnExpand), which already ends exactly when focus lands.
The regression test replays the document-level bubbling order that
fireEvent on the button alone does not exercise.
Keep the 2026-07-21 serial-reference note current with the ci.yml change: the
standard-hosted serial / linux definition no longer exists (removed as dead
code), and the current serial / windows definition is the in-house standby, not
a disabled standard-hosted job. Re-record the translation-pair hashes.
serial-linux (hosted ubuntu-latest) has been `if: false` since 2026-07-30 and
never runs. Remove the dead job block and retire the dangling references:
- TODO(hosted-serial-ci) narrowed to the single remaining disabled hosted
serial job (serial-macos); the hosted linux definition is gone.
- The cache producer comment no longer claims serial-linux refreshes the
hosted pnpm/Playwright caches; there is currently no active master producer
for them, so restores are cold on a lockfile change.
- The self-hosted standby's frozen-archive comment no longer cross-references
the deleted job.
- serial-macos gains its own intro comment since the shared 'hosted reference
jobs below are disabled' lede was removed.
No runner allocation, required gate, or all-checks-passed.needs reference this
job; the aggregate is unchanged.
The upstream-type proof only ran covariantly, so it caught a profile
field wider than pi-ai's but not one narrower — the direction its own
JSDoc claimed to guard. It now asserts both directions; the reverse holds
today because every field is either derived from upstream or a boolean.
`ModelCompat` gained `BedrockCompat`, which the gate had already started
serving, and the per-field protocol lists now match what the gates
resolve: `docs/config-catalog.md` pastes that JSDoc verbatim, so a stale
list there contradicted the README in the same change. The interface
header names the Responses grouping, since a catalog reader never sees
the README passage that explains it.
Valueless keys are judged after the name, so a withheld or misspelled key
written bare is refused for being that name rather than sent back for a
value it would be refused with anyway; the remedy no longer promises an
installed catalog value that a hand-declared route does not have. The
check covers `undefined` beside `null`: schemastery keeps the key either
way, and a cordis.yml entry reaches that state through `!!js undefined`,
so it is a config boundary rather than a typed one.
Coverage follows the composed path: the rejection is asserted through a
written settings section, and a switch is carried from that section onto
the wire a provider receives.
Refs #2646
The message-feedback note editor previously expanded inline inside the
assistant message's shared IconActions row, overflowing the row at every
viewport and pushing the branch action and the clock out of the column.
Rework it into a portable popover: the note editor is a fixed-position panel
portaled to document.body and anchored to the note trigger, so the row keeps
its single 28px line whether the editor is open or not and the panel escapes
the column's overflow clip.
The like/dislike buttons and the note trigger stay in the row unchanged; the
trigger toggles the popover (textarea + Save/Cancel + note-save failure) which
auto-focuses the input and closes on Escape or an outside click, returning
focus to the trigger. Rating/list-load failures surface in the row, note-save
failures inside the popover. Reuse the Menu portal surface tokens and add
@types/react-dom so the createPortal usage typechecks.
Layout e2e sweeps six viewports and pins that opening the editor leaves the
row's overflow, line count, and out-of-column items unchanged, and that the
panel is outside the column, within the viewport, and anchored to its trigger.
Unit tests cover the popover's portal-to-body, toggle, Escape/outside-click
dismissal, and unmount early-returns.
The full switch list already exists and is generated from source, so the
guide needs a way in rather than a copy: `config-catalog.md` carries 107
plugin sections, and linking the whole file leaves a reader to find the
one that configures the page they are on. Both mentions now deep-link the
`dsh-llm-pi-ai` anchor.
Refs #2646
The Models page has no field for `compat`, and the symptom it addresses —
a gateway holding a working key at a reachable address while refusing
every request — reads as a credential or connectivity problem. Give it
the same treatment `input` already has: name the symptom, show the two
switches that account for most of it, and state the resolution order.
Refs #2646