You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 474b7cc
Browse filesBrowse the repository at this point in the historyBrowse files
fix: second adversarial pass (git, client shell, server limits, regressions)
- git: never look inside submodules (their own filters ran via diff); fail closed when the driver
listing is cut; re-list drivers per operation (included configs); rename limits, UTF-8 log
output and --root forced; a timed-out diff is truncated, not clean.
- server: a shell that cannot start no longer exits the server, at most 64 shells; index deletes
are not quadratic; git status refresh is throttled, not starved; search reports symlinked
matches under the real path and falls back to the index in an ignored folder.
- client: open() line races, events-socket resync, Changes refresh on edits, Cmd+B/J in the
terminal, image blob URLs revoked, IME Enter, stale gutter base, tooltips escaped; settings
saved as merged PATCHes of changed keys, tabs: roots pruned, layout flushed on close.
- terminal: a capped REP leaves the cursor where the full count would.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Px3ERqxxjWWCw6ty21M5S
Copy file name to clipboardExpand all lines: DESIGN.md
+12-1Lines changed: 12 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -995,5 +995,16 @@ each finding below was reproduced before it was fixed.
995
995
| If the new install could not be moved in and the old one not moved back, the staging dir (holding the only copy) was deleted. | It is kept, and the error names it. |
996
996
| Relaunch after an update dropped `--host` and `--shell`. | Forwarded (`--port` is not: the old process still holds it). |
997
997
| Release signing ran in a job whose third-party actions were pinned by mutable tags, and checkout left the job token in `.git/config` for the build. | Actions pinned to the commits their tags named (checkout v5.1.0, setup-bun v2.2.0, attest-build-provenance v4.2.2); `persist-credentials: false`. |
998
-
| Not changed: signing still shares the build job (moving it to its own job is a workflow redesign); `codesign --verify` without a requirement only proves a consistent signature (releases are ad hoc signed); a Linux update drops a setuid `chrome-sandbox`; redirects of signed downloads are not host-checked (the signature covers them). | — |
998
+
| Security (critical). `git diff` looked inside submodules (it runs `git status` in each), and a submodule's own config is never read by the overrides: its filter ran from the Changes view. |`diff.ignoreSubmodules=all` in `HARDEN` and `--ignore-submodules=all` on the diff. |
999
+
| Security (critical). The driver listing was capped at 1 MiB and parsed even when cut: a config padded past the cap left the drivers after it armed. | 16 MiB, and a cut or failed listing fails closed: no git call runs. |
1000
+
| Security. The overrides were cached until `.git/config` changed, but a config can include files the watcher does not see (a tracked file via `include.path`, `~/.gitconfig`): a driver added there later ran. | The drivers are listed again at the start of each operation (status, changes, blame, history, base, file list). |
1001
+
|`diff.renameLimit=0` made status and Changes run into the 30 s timeout on large renames and come back as a clean tree; `i18n.logOutputEncoding=UTF-16` broke history, blame and the HEAD line; `log.showRoot=false` dropped the commit that added a file. | Rename limits of 1000, UTF-8 log output and `--root` forced; a timed-out diff is reported as truncated. |
1002
+
| Search found nothing in a viewed folder that is itself git-ignored (git lists no files there). | An empty git list falls back to the file index. |
1003
+
| A shell that could not start (deleted folder, bad `--shell`, out of fds) threw in the socket handler and exited the server; sessions were unlimited. | That terminal gets an exit notice and is closed; at most 64 live shells. |
1004
+
| Deleting files rescanned the whole index per path: a 1 500-file `rm` froze the server for 20 s on a 200 000-file tree. | Only a path that was a directory is scanned for children. |
1005
+
| A file written more often than every 200 ms (a log) held git status back for as long as it was written: every poke restarted the wait. | Throttled: a pending refresh keeps its time. |
1006
+
| Regressions from the first pass: a capped REP left the cursor elsewhere; heavy-dir events restarted the index build; search reported a match under a symlink instead of its target; tooltips still showed raw names; two doc comments ended up on the wrong code. | REP runs the cap plus the remainder of one row's period; heavy dirs don't invalidate; a link whose target is also listed is skipped; tooltips escaped per line; comments moved. |
1007
+
| Client: a second jump into a file still loading was undone by the first; reconnecting the events socket resynced nothing; Changes counts went stale on a second edit of a modified file; ⌘B/⌘J did nothing from the terminal on macOS; image tabs never revoked their blob: URLs; Enter confirming an IME composition ran the palette's top item; the change gutter kept an old HEAD base after a discarded fetch. | Each fixed; the reproductions were rerun in Chromium against the build. |
1008
+
| Settings: each window PUT its whole snapshot, so two windows (or two folders) erased each other's keys, the snapshot grew forever (`tabs:<root>`), and over 64 KB the save on close was dropped (keepalive limit); a layout change in the last 200 ms was lost. |`PATCH /api/settings` with only the changed keys, merged on the server in the write queue; the 100 most recent `tabs:` roots are kept; layout flushes before the save on close. |
1009
+
| Not changed: signing still shares the build job; the index caps file count, not path bytes or directories; the recursive watcher can use the account's whole inotify budget on huge trees; `/api/list` on a 1M-entry directory takes ~10 s (sort); a repository path containing a newline gets no git integration; OSC 8 links stop for good after 65 534 distinct targets (moving it to its own job is a workflow redesign); `codesign --verify` without a requirement only proves a consistent signature (releases are ad hoc signed); a Linux update drops a setuid `chrome-sandbox`; redirects of signed downloads are not host-checked (the signature covers them). | — |
0 commit comments