Repository navigation
Batch: terminal, Git, worktree, update guard, Share this host and crash fixes (#348, #351 to #358, #360 to #362, #366) - #365
Merged
Merged
Conversation
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Records how the 13 findings of round 2 were handled, and the state of the #350 design rework. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
A native surface now hides only when a lease's rectangle overlaps it; a lease without a rectangle still hides every surface. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…tall (#357) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erlaps it (#358) Popover, Menu, Select, Combobox and Autocomplete lease their positioner's rectangle while it carries data-open and follow it frame by frame; a kept-mounted closed popup holds no lease. Tooltips take none; dialogs keep their full lease. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…ading (#348) A late font changes xterm's cell without changing the mount box, so the ResizeObserver stays silent and the fit addon proposes from the cached cell size. The mount observer now listens for document.fonts loadingdone, re-measures the cell and runs the usual layout and repaint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a failed state query from an answer (#357) A sessionStorage marker restores the block when the window loads; only a confirmed state with no remote requester clears it. The bridge's getUpdateState now rejects on a native failure and falls back only when the desktop lacks the command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…loads (#348) The font effect ran only on a font or visibility change, so a renderer created later (an AI terminal waiting for host config) was never repainted after the bundled font loaded. It now re-runs for each committed renderer epoch and re-measures the cell before the layout and repaint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ery deadline (#353) The shared specs run in one worker, so the probe in `before` ran once for all of them. `beforeTest` now probes first, and the probe, stop, relaunch, session reload and mock restore share one 100 s deadline inside the 120 s test allowance. Failure evidence in `afterTest` tolerates a dead webview so the worker's later tests still reach their probe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The popover keeps its content mounted while closed, so the search typed before survived. Key the content by opening, counted on every closed-to-open change of the open state, so the trigger, the composer shortcut and the controlled prop all start a fresh search. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
… it when no remote install runs (#357) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he bridge only (#357) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cisions (#348) A ring of the last 200 sizing and repaint decisions (trigger, generation, mount box, fitted and applied grid, role, pixel ratio, font status, renderer, request and outcome, repaint), off by default and enabled only in development from window.__bibcodeTerminalSizeDiagnostics. It records no ids and nothing written to the terminal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r the installing dialog (#357) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… nothing (#348) A second press after the server declined the claim sent nothing and showed nothing. The size notice now adds "The server kept this size." in its existing status region until the applied size changes or a claim is sent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the workspace (#358) The read-only rendered view now passes the file's path to ChatMarkdown, whose image renders through the rich editor's loader when a path, a thread and a workspace are known, so a relative image is read from the workspace and a path that leaves it is refused. Chat messages pass no path and keep a plain image. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ending Check again on a push (#357) A completed install clears the requester while the phase stays installing until the restart, so only a cleared requester outside protecting and installing ends the block. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the app cannot be reached (#357) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…353) The 1 s tick rebuilt `values` with a fresh object each time, so the values view rendered three times across three ticks with an unchanged reading. Compare its props by content and keep it memoized; a changed reading or uptime text still renders it. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…353) Another running instance's image, or a stale one a killed instance left, was shown as a full read-only volume because the `.mount_` marker also required this process's executable under the mount. The marker now stands alone; the file-system-name marker still needs the executable. The two assertions of the_running_app_image_mount_is_hidden_before_it_is_read that pinned the old behavior are rewritten on purpose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fixed class (#358) A refused pairing offer logged its reason at debug, and a refused pairing credential logged nothing, so a one-off "Invalid pairing token" left no trace. The offer refusal is now a warn with its trace id and fixed reason. consume_grant logs each refusal once at warn with a fixed class (empty, unknown, revoked, already_used, expired, proof_key_mismatch, desktop_bootstrap_expired, unclassified). The persisted store names the class with one read of the kept row on the refusal path only. Nothing that identifies the credential, link, device or address is logged, and the HTTP responses are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…und (#353) The removal test bounded the whole removal (plan, Git, SQLite) with a 2 s timeout, so a loaded machine failed it before the drain. It now waits on the drain having been entered and on the removal's result, with 30 s guards only a real hang reaches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…exists A missing parent cannot be told apart from an unmounted volume, so the audit now keeps the record, both when it reads the records and when it re-checks before the reap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
) The Tailscale HTTPS switch, its setup and disable dialogs, the stored Serve preference and the desktop command that changed it are gone. The command stays registered and answers the unsupported payload; stored keys are ignored. A MagicDNS HTTPS address is listed only when a Serve set up outside BiBCode already answers BiBCode's well-known endpoint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and explain an address read failure (#361) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…TTPS default, and say what a locked failure restarts (#361) A rule is ours only when it names this program or reads as it did when this process added it. The default address is chosen once over every listed address. An unanswered legacy MagicDNS endpoint and an empty This environment section are not shown. A firewall failure under the lock avoids the wide restart; recovery still restarts local-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tecture contract test (#361) Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…r is time order (#358) The store compares RFC 3339 text (`expires_at > ?`), but format_iso trimmed the fraction, so `…:00Z` sorted after `…:00.001Z`. A pairing link, session or offer whose expiry fell on a trimmed fraction stayed valid for up to a second after it expired. That is why the persisted refusal test accepted its -1 ms link about one run in ten under load. format_iso now always writes three fraction digits, which still parses as RFC 3339. The refusal assertion now prints what it got, and two tests pin the order and the refusal one millisecond after expiry with explicit timestamps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…on fails The Windows VM sees a third finding at the interrupted-removal count now and then. The count assertions now print each finding's id, severity, count and summary (mode and reason token, never a path). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… s sleep The test slept 1 s and assumed the removal plan had finished. A slow plan (the Windows VM) saw the interrupt itself and raised a repository-mismatch finding. The test now waits on the drain-entered signal, which the removal services expose to integration tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t test diagnosis Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
gitlab_poller_auth_failure_ends_every_subscriber_and_deletes_host_rows jumped the paused clock 10 s every 200 real steps. Under load the git scope read (10 s budget) or the glab tick probe (5 s) was still running, so its deadline fired and the subscription ended with timeout instead of not_authenticated. The clock now moves only after both subscribers joined and no tick is in flight, under a 60 s real-time guard. Reproduced 24 of 160 runs under load; 0 of 160 after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l gates Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…lisecond width (#362) SQLite compares these timestamps as text, and the time crate's Rfc3339 trims the fraction, so `…:00Z` sorts after `…:00.001Z`. Beyond the pairing path fixed earlier, the OAuth cleanup could delete a live session's refresh token up to a second early, and the server's now-helpers fed the same variable-width text into expiry, retention and pruning cutoffs, MAX() of last activity, and created_at keysets and ORDER BY, beside fixed-width strftime and client values. One formatter, persistence::format_timestamp, now writes RFC 3339 UTC with exactly three fraction digits (SQLite's %f and toISOString form). auth::format_iso, the repositories' cleanup and every SQL-bound now-helper call it. Values from now_utc lose their sub-millisecond part; epoch-millisecond values parse unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-dc3c33 # Conflicts: # tools/objc-exception-probe/src/firewall_argv_echo.rs
#362) Three fraction digits tied rows written within one millisecond, where the older trimmed text almost never did: a turn's later assistant message with the lower id lost to the earlier one, a turn starting in the compaction's millisecond failed the strict `>` and skipped the guard, and a 3-digit cutoff could delete a longer row under a millisecond early. The store form is now RFC 3339 UTC with exactly nine fraction digits: clock values keep their nanoseconds, epoch-millisecond values are zero-padded, and every server-written operand shares one width. The compaction query moves to a named constant so a test can run it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l gates Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1724face0c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… admits this program (#361) A rule that was disabled or changed to block still names the program in the netsh listing, so it was kept and an offer was made while inbound stayed blocked. Before keeping a rule, read its stored fields with reg.exe query: enabled, allow, inbound and this path. The fields are fixed tokens, unlike the localized listing, and a standard user can read them. Otherwise the rule is replaced as a rule for another path is. An unreadable store keeps the listing's word and logs a warning. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…r's one form (#366) A client writes toISOString's three fraction digits, and the store compares timestamps as text at nine, so a client message or turn sorted after a server row of the same millisecond. The public command decoder now re-writes every client createdAt, updatedAt, completedAt and implementedAt that parses as RFC 3339 in the store form before the command is decoded; text that does not parse is kept and stored as sent, as before. Imported agent-session times use the same shared formatter instead of their own three-digit one. This also covers the compaction guard's requested_at fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
) The client timestamp rewrite walked the whole command JSON and changed any key named createdAt, updatedAt, completedAt or implementedAt, so a user's answer to a question whose id is createdAt reached the provider re-written. It now touches only explicit paths: those four fields at the command's root, and per command type bootstrap.createThread.createdAt (thread.turn.start), messages[*].createdAt (thread.history.import), proposedPlan.createdAt, updatedAt and implementedAt (thread.proposed-plan.upsert), activity.createdAt (thread.activity.append) and session.updatedAt (thread.session.set). Answers, tool payloads, provider data and message text stay byte for byte. The payload digest is still taken from the bytes as sent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
mubeda
added a commit
that referenced
this pull request
Nov 14, 2026
Bump every version source to 0.16.0 and turn the Unreleased CHANGELOG section (PRs #349, #359, #365 and #369) into the v0.16.0 entry. Raise the Claude Code additive-hook ceiling to 2.1.323 after the live PreToolUse guard proof passed on that build, and move the above-ceiling test example to 2.1.324. Give the CI Test lookup contract test a 30-second limit: it runs bash and jq eleven times and timed out against the 5-second default under load. Verified locally: cargo check for the workspace, vp check, vp run typecheck, the full vp run -r --concurrency-limit 1 test graph in all nine packages, release:smoke, the updater regression sets, cargo test -p bibcode-desktop, and the macOS arm64 DMG signature and Finder icon check. CI: the Seeded Packaged Desktop Upgrade workflow from v0.8.0 passed on all seven lanes for this branch (macOS x64 on a rerun after its hosted runner lost its connection). Reviewed by Codex with no findings. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
One batch of fixes for the issues that were open on 2026-11-13, planned in
docs/plans/2026-11-13-issue-batch-348-358/(triage, evidence, spec, plan, phases, progress log, reviews). Every item of every issue was checked against the code first and got one disposition: fixed with a test that failed first, decided by a recorded test or probe, or recorded as a limit in code or docs.fatal:line; the pull and hook limits of the index-lock cleanup are recorded; two doc entries added.terminalSizeHandOvercapability; a new terminal retries WebGL; refused pairings are logged atwarnwith a fixed class; the model picker reopens empty; the read-only Markdown view loads relative images from the workspace.client.render-error.#350 (a server-side terminal screen) was closed as not planned by the owner. Its design, three design reviews and the results of a serializer proof are kept in
docs/plans/2026-11-13-terminal-screen-350/.Diagnoses worth reading
85x33, then85x30). A re-measured font, a pixel-ratio change and the bundled-font load now wait for the layout to settle.Decisions by the owner
Agent's calls recorded in the spec for the owner to confirm: "Manage devices" is disabled during an install instead of being shown above the installing dialog; a failed lookup's 5-second backoff and the 5-minute rule for a remembered pull request; a creation record is reaped only when its parent directory exists;
pullstays out of the index-lock cleanup list; tooltips take no preview lease.Limits, stated plainly
$, backtick,&,%, non-ASCII) through the sameShellExecuteExWcall to a stand-in program and got them back byte for byte. Hownetshitself reads its arguments, and an approved prompt ending in a pairing code, need a person at a Windows screen.reg.exe query; if that read fails, the listing's word is taken. The read was probed in the Windows 11 VM and the code passes Clippy and its tests there; no run disabled BiBCode's own rule on a real desktop.client.render-error: a reload inside the server's 5-second minimum between batches, or before the connection can send, loses the record. In the packaged build component names are minified, so the route pattern is the readable part.Validation
vp check --no-fmt,vp checkon every changed file,vp run typecheck,vp run check:contracts,vp run check:markdown-links,cargo fmt --all --check,cargo clippy --workspace --all-targets -- -D warningscargo test -p bibcode-server;cargo test -p bibcode-desktopmain); both exit 0 with no failed test on the final headchat-reasoning-rowson the fixvp check --no-fmt, desktop tests, firewall argument probe (at the commit before the timestamp widening and the merge ofmain)Two more tests that depended on timing were fixed along the way, without product changes: the profiler worktree audit test (a fixed 1-second wait) and a GitLab poller test (a paused clock moved while a child process was still running; 24 of 160 failed under load before, 0 of 160 after).
Whole-suite runs on Windows at an earlier commit also failed tests this branch does not touch, on a VM sharing the host with other builds: two Git index-lock tests (
background_status_does_not_break_a_concurrent_git_addand its linked-worktree variant) and shutdown or single-flight timeouts. On macOS two script tests with a 5-second limit (ci-platform-contract.test.ts,bibcode-identity.test.ts) timed out inside a loaded full run and passed alone. Neither is changed here. On Windows, whole-treevp checkreported formatting in files underdocs/plansonly, which pass on macOS; CI decides.Reviews: the plan had two Codex reviews (22 and 13 findings, all handled); the code had Codex reviews of the whole branch and of each later addition, with every finding verified against the code and fixed or rejected with a reason in the plan log.
Profiler: on for every packaged run. No finding caused by this change. Pre-existing on the labs:
client.stalland onecpu.sustainedon the web process under software rendering, andrpc.slowfor Git ref listing and partial staging on the Windows VM. Profiler coverage of the change: a new quiesce steppull-request-lookups(timed by the existing step marks); a newworktree.removalmodecreate-rollback; a new client event and findingclient.render-errorthrough the existing client batch, redacted on both sides; newwarnlogs carry fixed classes and never a credential, URL or path; the Tailscale status read reports its exit.React and
UI.md: changed components and hooks were reviewed againstvercel-react-best-practices, and changed screens, dialogs and messages againstUI.md.Runbooks:
docs/testing/cross-platform-validation.mdandwindows-desktop.mdwere updated;linux-desktop.mdandmacos-desktop.mdwere reviewed and remain accurate.Closes #348, closes #351, closes #352, closes #353, closes #354, closes #355, closes #356, closes #357, closes #358, closes #360, closes #361, closes #362, closes #366.
🤖 Generated with Claude Code