Skip to content

Batch: 12 quality-loop fixes, one CI run (owner decision 2026-09-25) - #1318

Merged
Juliusolsson05 merged 108 commits into
mainfrom
integration/batch-2026-09-25-a
Sep 25, 2026
Merged

Juliusolsson05 merged 108 commits into
mainfrom
integration/batch-2026-09-25-a

Conversation

@Juliusolsson05

@Juliusolsson05 Juliusolsson05 commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Integration batch per the owner's decision (ledger §7.4): the ready quality-loop PRs are merged here, CI runs once on the combined tree, and this merges to main with --merge. Each member's head lands in main, so GitHub marks each member PR merged.

This PR stays a DRAFT until every member passes its own gate (steering q39): three reviews with no unfixed blocker, a public final disposition, an accurate body, and checked closing keywords. A member that fails is removed and the batch rebuilt.

PR What Gate
#1257 One invalid TLDR/Goal record no longer breaks TLDR for every agent disposition posted
#1263 Workspace save failures shown to the user disposition posted
#1310 Paste confirmation across wrapped CJK text (refs #1292) disposition posted
#1311 Raw PTY view survives a same-id wake (refs #1281) disposition posted
#1312 A bulk provider switch can be stopped disposition posted
#1284 Claude proxy request bodies capped per events file (refs #1273) disposition posted
#1287 A goal loop follows its pane when the agent is replaced disposition posted
#1298 Same-millisecond Codex rollout items not dropped disposition posted
#1286 New Agent overlay input fix, and safe spawn-failure messages disposition posted (C round-2 fix 0c5aa6d verified by the author against the code, not re-reviewed)
#1297 Conversation picker never acts on stale rows disposition posted
#1316 A new Pi pane's first prompt waits for its bridge disposition posted
#1317 codex-headless bump: proxy mirror chunks as base64 (refs #372) disposition posted

Excluded: #1221 and #1216 (UI features, the owner's call) and #1218 (Dependabot).

Main merged in after #1221 (keyboard-first) landed (e9b5260f, steering q41). Conflicts, each resolved to keep both sides' behaviour:

This also fixes main's red CI on 13ae6085: nine tests still used #1221's old accessible names.

A focused read-only review of the integration is running (temp/review-1318). This merges only when that review is clean AND CI on e9b5260f is green.

Earlier conflicts resolved here: src/shared/types/session.ts. #1263 and #1286 each add an independent constant (WORKSPACE_READ_ONLY_PREFIX, PROVIDER_CLI_NOT_FOUND_SUFFIX); both are kept. The claude-code-headless pointer is 64fd0eaf (main's, which already contains #1284's 2ce428cf), and codex-headless is d7d7a5d (#1317). npx tsc -b is clean on the combined tree.

🤖 Generated with Claude Code

Juliusolsson05 and others added 30 commits September 25, 2026 04:12
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he whole store

One record that fails validation, such as an over-limit text from a newer
build before a downgrade (the owner's real file already has one AT the
400-char limit) or a half-written completion, made every read and write
of the store throw. Every agent's tldr_update and goal_set failed, the
peeks and Agent Activity went empty, and the enforcement hooks threw.
The validator itself threw instead of returning false. Invalid records
are now set aside per identity, the original bytes are preserved beside
the file (named by digest, one copy), and a malformed container still
refuses.

Closes #1247

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y, carry revisions

- A crash mid-copy left a partial file under the final name, and its
  existence was taken as proof the evidence was safe. Copies are now
  published with temp + rename, and an existing copy counts only if its
  bytes are identical.
- One unreadable history entry read as an empty history, so the next
  report replaced that identity's whole timeline. The raw file is now
  preserved (without a .json name, so eviction never counts or deletes it)
  and every entry that still validates is kept.
- An identity reporting again after its record was set aside restarted
  at revision 1, which every reader discards as stale. It now continues
  above the set-aside revision.
- The copy's 0600 mode is pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ait for it

Review B: preservation failing (a read-only directory, a full disk) made
every READ of a store with one set-aside record throw again, which is
#1247's symptom. Reads now succeed; the copy is owed before the first
write, which retries it and is refused if it still cannot be made, so
nothing is dropped unpreserved. Pinned: an over-limit completion note, an
over-limit history entry, and reads never answering an inherited property
name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…versized ones move aside unread

Review A (round 2): when even the raw read failed, the history fell back
to empty and the next report replaced the file uncopied; it now throws
(the report still succeeds, and history failures stay non-fatal) and
leaves the file untouched. Salvage also bypassed the reader's 512 KiB cap
by loading the whole file; an oversized history is now renamed aside
without being read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A full disk or a permission change made every workspace.json save fail;
autosave only logged a warning and retried forever while the user kept
working on changes lost at quit. After three consecutive failures the
storage error (without Electron's IPC wrapper) now shows in RestoreBanner
("Workspace changes are not being saved: ..."), clearing on the first
successful save. A restore problem still takes precedence, the collapsed
chip reads "Not saving", and the main-side comment that claimed this
already happened is corrected.

Closes #1244

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…el the state honestly

- Both reviewers: the failure count rode on the backoff position, which
  every edit resets, so a user who kept typing on a full disk (the #1244
  case exactly) never saw the banner. Rejected saves are now counted
  separately and reset only by a successful save.
- Both: the expanded banner said "AUTOSAVE OFF" while its text said saves
  keep retrying. Expanded and collapsed now read "Not saving" (restore
  problems keep "Autosave off"), and the aria labels read naturally.
- Review A: the copy no longer promises that freeing space or fixing
  permissions will help; some causes (a workspace.json this build refuses
  to write) are not those.
- Review B: the threshold is pinned as a literal 3, the chip is tested,
  and the test's refs are complete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed per events file (#1273)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… after a failed create

- #1269: the overlay is retained under display:none by takeovers and the
  fullscreen editor, and the palette can open it there. Its capture
  listener ate Escape/arrows/Enter and its owner marker (a querySelector,
  blind to display:none) blocked every shortcut. Hidden, it now renders
  nothing and listens to nothing; `open` is kept so it appears when its
  surface returns. GlobalEditorWorkspaceSlot now provides the retained-
  surface hidden context too.
- #1270: a create that produced no session left the one-shot latch set, so
  Enter was dead in an overlay that still blocked input. It reopens.
- q22: the three spawn-failure toasts in pane.ts showed the raw IPC
  rejection; they now show SESSION_START_FAILED_MESSAGE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1279)

Loops are keyed by session id, and every replacement path gives the pane a
new one. The loop stayed under the dead id, so the pane, Resume/Stop and the
new process's goal_loop_complete all missed it. The renderer, which commits
the old -> new swap, now tells main (goal-loop:carry). Main moves the loop,
paused as interrupted (the restart rule: never blind-continue into a process
that has not proved its hooks), and never overwrites a successor's own loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e body budget

Omitting bodies past the budget left the debug bundle's 5 MiB tail with no
prompt text. claude-code-headless (bumped to 47bb4cf) now keeps the newest
body alone in latest-request-body.json; the bundle reader appends it after
the events tail, as its own kind, so a bundle always carries the current
conversation. Also picks up the zero-budget first-request fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ps no sidecar body (q26)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rowing

CI for #1266 (0c962aa) failed 'resumes the highlighted row…': Enter
resumed row 0 because the picker's head-keyed highlight reset (a passive
effect) flushed after the test's ArrowDown. findByText resolves when the
rows paint, not when effects settle. Flush, then confirm the arrow landed.
Ordering only, no wider timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved (steering q41 overlaps):
- RestoreBanner: main's swap/focus + button styling, with the batch's
  save-failure label; the two test files combined on one mutable context.
- BulkProviderSwitchModal: main's DialogActions footer, with #1312's stop
  (Cancel becomes "Stop after this agent" while locked).
- NewAgentPlacementOverlay: main's list keys under #1286's `active` gate;
  main's new listbox autofocus is gated on `active` too (a hidden overlay
  must not take focus).
- pane.ts: #1286's spawnFailureToast over main's raw err.message toasts
  (q22).
- ConversationsPicker: main's useListNavigation, with #1297's stale guard
  before nav.onKeyDown for every list key (PageUp/Down, Home/End, ⌃N/⌃P),
  hover stripped while stale, and `stale` in the reset key.
Also fixes main's red CI on 13ae608: nine tests still queried #1221's old
accessible names ("everywhere", the recorder's "Add"/"Press keys…").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Juliusolsson05
Juliusolsson05 marked this pull request as ready for review September 25, 2026 18:02
@Juliusolsson05

Copy link
Copy Markdown
Owner Author

Merging on the owner's explicit instruction ("it is safe enough now, yolo merge it"), before CI on e9b5260f and the focused integration review finished. Locally: npx tsc -b is clean and 688 tests pass across the touched areas.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant