| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
| |
never takes a serial the old session handed out
A Restore carried next_serial over for panes but started column serials at
1 again. So a restored column could take the serial a deleted column had,
and a script holding col/<n> from before the Restore would find a different
column there. The column counter is now carried over like the pane one, and
restoredcol maps each old serial to a fresh one.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
a refused line is quoted with its control bytes shown as blanks
fs.md already promised that the whole of a write to /ctl, a pane's ctl and
a column's ctl is checked first, as it is for exec and look. But a ctl write
ran its lines one by one, so a line holding a control byte gave that line's
own, misleading reason ("unknown command"). Worse, the reason quoted the raw
byte back into the err record. The check now happens in tree.write before
anything runs, with the same EINVAL and reason exec gives. A refusal's quoted
line shows control bytes as blanks, so an err record never carries a raw
escape.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
`>` write leaves the tag as it was
A column's or the workspace's tag took any length, so a write past 4096 bytes went in and a later Dump failed on it (bad dump tag), and a truncating open wiped any tag before the write after it could be refused. The column and workspace tags now refuse what a pane tag refuses: the 4096-byte limit (ENOSPC, tag: no space: over 4096 bytes) as well as the control characters they already did. A truncation of any of the three is held until the write after it is known to fit, and done with it; a refused write drops it; a close or read with no write after it does it then (so `: > tag` still clears). A test runs a truncating write too long, a control character and a bare truncation at each kind, and Dumps after. docs/fs.md says so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
whole body: 60 KB appends go from 35.7 to 2.1 ms each
Round 25 measured bulk body writes at about 8 ms a write. There is no frame wait in it: a profile of open, write, clunk in a loop found the flush of each close walking the whole body five times. dotOf, setDot and showOffset turned the cursor between offsets and rows by counting every newline from the top; setContent found the line index's changed span by comparing old and new byte for byte, and hashed the new text to see whether it was back to the saved one. The rows now come from the file's line index by binary search (checked against the counting at every offset), a splice tells setContent the span it changed, and the text is hashed only when its length is the saved text's. Measured over 9P on a Debug build: 60 KB appends 35.7 to 2.1 ms, 8 KB 5.3 to 0.8 ms, 1 KB 1.3 to 0.9 ms. What is left is two copies of the text an edit (the splice's and the undo snapshot's). The perf gate gains body-appends, 64 appends of 8 KB on the 50k-line file, and its three baselines are recorded again.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
step's sweep, are scratch: the cached ones are freed, not overwritten
dropPane clears the rows cache's pane but keeps its allocations until the next step's sweep, since they may still be borrowed. shellRows took a cache with no pane as free and wrote a new gpa-built entry over it, leaking the old one: the 9P monkey's seed 109 (a look searching a terminal after its pane was torn down in the same step) ended its session with the debug allocator's leak panic. A slot still holding rows now gets scratch rows, as one holding another pane's already did. A unit test drops and asks again under the testing allocator (it leaks without this).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
untouched: the GUI no longer calls into a freed one at startup
listen started the editor's turn and pointed its answer_held and wake_parked hooks at the new Listener, then, when socketPath found the path too long for sun_path (108 bytes), freed the Listener with gpa.destroy while the hooks stayed set; the GUI's next rest (waitInput) called answerHeld on freed memory and died with SIGSEGV. The lapis bench's runs crashed for 12-character names in an 82-byte runtime directory (a 110-byte path) and not for shorter ones. The path is checked before anything is made; a unit test asks listen for a name too long and finds the turn's hooks clear and the turn not started.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\
| |
| |
| |
| |
| | |
Merge: audit top-five cuts + tag sweeps + Config/DumpConfig (on the audit bug fixes C9, C2).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
workspace tag reads Dump Themes Config Debug Exit
Config (SPC f c) opens init, found as the settings report finds it
(opts.startup_config_path: $XDG_CONFIG_HOME/pardes/init or
~/.config/pardes/init, and the macOS and Windows paths config.md gives). A
pane that already holds it is gone to instead; a file on disk is looked at;
with none, an empty pane is named for it, and Save makes its directory and
any above it first (File.make_dirs, fs.makeDirs) before writing. Without a
configuration directory it says so and opens nothing.
The report Config used to open, the startup path and every live setting, is
DumpConfig, in a +DumpConfig pane. No alias keeps the old meaning.
The workspace tag's default words put Themes where NextColor was, NextColor
staying a builtin, and Config beside it. A tag the user edited is kept as it
was: a dump stores only an edited one (topbar_custom), and a restore puts
back only that.
theme.snap types NextColor onto the workspace tag to click it, and tagnav's
walk back to Dump takes five long-word steps. The rest of the re-recorded
goldens differ in the workspace words and their widths only.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
for what it swept, as a pane tag's does
Both headers acted on the press: a middle or right press ran, or looked
for, the word under it (or the header's selection when it was on that) at
once, so a drag had nothing left to do. A sweep of `echo SWEPT` in a column
tag ran a bare `echo`. They have done so since the headers were drawn apart
from the panes; it is no regression, and the -l/Restore allocator fix
(ompukopz) does not touch it.
Now a press on a header holds a HeaderSweep (the column by its serial, or
the workspace), which the drag extends, held to the header's row and text
as a pane tag's sweep is. It is painted in its button's tint meanwhile, and
the release runs what it swept in that header's context; a release that has
not moved runs the word or selection a click always did. The other of
middle and right cancels it (acme 2-3/3-2); the select button is inert, as
a header's command already takes the held selection as its argument.
Running on the release, a builtin from a header is announced as one from a
pane tag is: the press used to set the announcement and the release clear it
at once. find, restore, theme, topbarexec, ttyhelp, tutor and windowops
re-recorded for that badge alone.
headersweep.snap sweeps the column and workspace tags with the middle
button and a word part with the right one, and cancels a sweep;
headersweep-restored.snap sweeps both after Dump and Restore.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
formats, and three orphan test scripts go
A2: a restored pane's tag tail comes from the dump's tag_tail, which every dump since 0.0.4 writes; the 27 earlier default tails that were recognised to upgrade, restoreTail, tailClass, savedPrefix and restoreTailAt, pdf_view's and image's legacySavedPrefix, a terminal's TTY tag prefix and its raw output tail replay, and the ThemeSel, FontSel and ColumnTags words (init lines and dumped output names) go, with their tests; the CHANGELOG says so. A4: test/fs_soak.py, referenced nowhere (monkey9p.py does its work). A6: test/column_grip.py and test/look_placement.py, referenced nowhere; the six review scripts docs/ui-review.md names stay.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
host_io's, once, where the tty, the gui and the detached session each had a copy
writeFile, writeDump and dumpThemes were byte-for-byte the same in tty.zig, gui.zig and detached/server.zig but for how each reaches its core, and the gui's and the session's reapers the same but for a pid <= 0 against == 0 (a pid is never negative there). Each vtable entry is now a line calling host_io's. ttyTaken, fgName, killJob and ptyResize stay each shell's: they are already one call to host_io each, and what differs is how a shell reaches its pty (an optional with a file, an optional with an fd, a bounds-checked array). macos.zig keeps its copies (no macOS build here to check it). No behaviour changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
other language does: the in-process ZLS backend goes
lsp_zls.zig (1,522 lines), the zls dependency, build.zig's zls wiring and the import graph it baked into the options only for it, and main.zig's reference go. lsp_client's table gains a zls row (PARDES_LSP_ZIG overrides it); Hover, Rename, Diagnostics, WsSymbols, Lspinfo and gd answer through it (checked with lspprobe and the snapshots against zls 0.16.1-dev). What changes for a user: zls must be on PATH; a completion's rows are zls's candidates at the cursor, where the linked analyser gave each one's declaration; document symbols carry no signature. The Zig snapshots (lsp, lspcomplete, lspcompletemoved, lspdebug, lsprelpath) run the real zls now: lspdebug reads the client's explain and report, lsprelpath spells gr's rows where it spelled a completion's, and their goldens are recorded again (stable over three runs). Lspinfo still opens with its backend line. The ReleaseFast tty binary is 105.35 MB to 96.28 MB, the Debug one 296.5 MB to 245.9 MB. docs/lsp.md, web.md, design.typ and the README say so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/
|
|
|
|
|
|
| |
copies, identical to their sources, go, and so does the label saying which was used
shaders/prebuilt/*.glsl were byte-identical to shaders/X.glsl or to prefix.glsl + post/X.glsl (checked with cmp, all 14), kept only so a -Dprebuilt-shaders build could name them; EffectCode and Config then labelled the GUI's shader source as live or prebuilt. The GUI embeds shaderSource (a concatenation, no glslc) either way now; the prebuilt SPIR-V stays, and zig build shaders refreshes only it. Config's report and EffectCode lose their GUI shader source line.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
map, vaxis_input.zig, for the tty, the gui and the board
The vaxis-to-Event key mapping was copied in tty.zig, gui.zig and esp32p4.zig, and the copies had drifted: the gui's (its stdin feed, which test windows and a gui started in a terminal read) had 9 arms against the tty's 26, without the function keys, Insert or the keypad, so they reached a terminal pane as private-use codepoints. vaxis_input.zig holds effCp, mapKey and keyEvent once; the gui posts through postKey, and a test runs F5, Insert and the keypad's Up through it into a terminal pane.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
workspace tags take several selections, and its 9P files have a time
dump.initDump copied Pardes.init's construction and had drifted from it: it never gave the column and workspace tags their allocator, so after -l or Restore they could not hold more than one selection, and never set fs.started, so every 9P mtime read 0. Pardes.create is now the one construction, allocators, tags, the tree's clock and the mounts, that init and initDump both start from.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ |
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
its next command in between
signalTty signalled the running job's group first, then scanned all of
/proc for the session's & jobs, then the shell. A job dead of the signal
lets a job-control shell run the line's next command, and once pids wrap
below the host's older processes the scan takes long enough for it to:
"sleep 0.4; touch killed" killed at 150ms touched the file. The host_io
test caught it every run after the pids wrapped (pid_max 4194304, new pids
near 17000, 229 older processes above them to scan). The shell's group now
goes first, then the session's groups, then the foreground one.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
namespace's lowercase name
The last of the deferred renames, now that the tty and theme agents have landed: panes.terminal at its importers, the alias lines in Text.zig and File.zig and panes.zig's own uses following. dump.zig's Terminal struct, a dump record, is not this. The served sources list and docs/design.typ name the new file. test/perf.zig's references change, so the three perf baselines take its new harness id with their numbers as recorded. No behaviour changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ \ |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
DMedblue #000099
acme tints nothing in a tag, but the tint is a pardes indicator the user
wants in every theme. #000099 is acme's own (draw.h DMedblue, its dirty
button): a navy that reads as ink until you look for it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
every theme draws a file's name, a +Name and the Tty word off the tag's ink
The faithful ports (neobones_dark, dracula, tokyonight, the *bones, ...),
every helix import and any theme file set no tag_name_fg, and ChromeTheme
fell back to the plain ink: their tags lost the accent the pardes themes
have. The user's neobones_dark looked tinted before only because the Sep 24
build had no such theme and fell back to orchard.
The tint is now derived when unset: the theme's keyword colour, else the
first of its ANSI accents, syntax, grip, selection or diagnostic colours
with a hue, placed at the lightness nearest the ink where the hue holds,
at least 4.5:1 on its ground (half a point under the ink's own where the
ink has less to spare) and 0.07 off the ink in OKLab. Each ground, plain and
focused, gets its own. A theme that names its tint keeps it exactly.
Tests: every theme's chrome keeps both tints off the ink and legible; every
theme draws a file's basename, +Errors and Tty+sh in a tint, focused or not.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
Locations setting and cache beside what uses them
Config (75 lines) was re-exported from locations.zig already, and Cache (213) served only its format; locations.zig is 683 lines with them. The cache's own Result, which would be ambiguous beside locations' Result in one file, is Cache.Hit, what its comment already called it. pardes.zig, dump.zig and main.zig import locations.zig. No behaviour changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| | |
Two functions (sameCell, columnAt) on Layer.TagHit, 32 lines with their imports, used by edit.zig, mouse.zig and look.zig: they sit with the type now, called Layer.sameCell and Layer.columnAt. docs/design.typ names Layer.zig in its place. No behaviour changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
lowercase name
The naming the split agreed on, deferred until now; panes.mini is its name at its importers. File.zig keeps its alias line (const Mini = panes.mini) so the file another agent is working in changes by that line alone. The served sources list and docs/design.typ name the new file. No behaviour changes; test/perf.zig's two references change, and since the perf harness is keyed by its own text, its three baselines are recorded again (under other agents' builds, so a little slower).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
the post chain's builds) takes a type's name
The naming the split agreed on: a file with fields is a type, TitleCase, as Messages.zig and Layer.zig are. Its importers bind it as ShaderBuild; comments and docs/render-pipeline.md name the new file. No behaviour changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
p.messages.at(i)
The rename deferred from the file split; no behaviour changes. Output.zig's one call follows.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | | |
| | \ | |
| | \ | |
| | \ | |
| |\ \ \ \
| | | |/
| | |/|
| | | | |
+ tty ssh acked frames
|
| | | | |
| | | |
| | | |
| | | | |
answer after each, and draws the latest state when it does
|
| | | | |
| | | |
| | | |
| | | | |
weighed up per cell in the tty
|
| | | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
pane under its tag and two rows, or is refused
A seeded sweep of placements (New, pane/new, Edit =, Tty, look, Delcol, deletes, refusals included) over screens 6 to 40 rows high found no refused placement that leaves a pane short since lyltlqnz and lrpzwyom; the pane a row short came from Newcol, which halves a column's width so long tags wrap onto more rows, raising those panes' minimums with no rows moved. Newcol now shares each such column's rows out again, and where a column has not the rows for every minimum there is no new column (Newcol: no space for a column: the panes' tags would not fit), as a size too small is refused. The sweep, 300 seeds, is the test; a user's drag or a tag grown by editing may still take a pane under, as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |/ /
| | |
| | |
| | |
| | |
| | | |
8192 was kept for round 24 because 64 KiB seemed to hang fs-test's restore detached space; that was the batch-wake overflow fixed in kmqtwqsm, which any msize could hit, and fs.py passes at 64 KiB with it. A client asking for more now gets it, so a write up to 64 KiB less 24 is one Twrite, and round 24's no-newline cutoff (write_room, the negotiated msize less 24) follows: fs.py checks a 20000-byte ctl line from a 64 KiB client is taken whole. Each of the 16 connection slots holds its buffers at the larger size.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
maps to ENOSPC as the docs say
The tree answers ENOSPC, but through a mount 9ns maps the words, and tag: over 4096 bytes carried none it knows, so a shell saw EIO. The words now hold no space; docs/fs.md says ENOSPC again.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
middle to …
An Rerror carries 128 bytes (Plan 9's ERRMAX) and the engine cut longer text there, and a builtin's failure was first clipped between words to 256 with ...: either way the end, which says why, was what went. tree.handle now fits a long reason by cutting the middle of its longest path, else of the whole text, on a character boundary, and reportFailure fills its buffer the same way.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
HOME needs
outPath made only the last directory, so on a HOME with no ~/.local/share the default DumpDir failed no such directory. It now makes each missing parent, as mkdir -p; the known-wrong line in docs/divergences.md goes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
does, and a start with no terminal says so
A name that did not exist yet failed resolveOs, so the launch fell through to starting an editor of its own, which on a pty with no controlling terminal (a detached session's) ended in a NoDevice error trace. A new name's directory is now resolved and the name kept: the launch reads pane/new and writes that path to the pane's name, so Save creates the file, and --wait waits on that pane (the git commit case). A standalone start whose /dev/tty will not open prints why and exits 1. fs.py covers both; the known-wrong line in docs/divergences.md goes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/ /
| |
| |
| |
| |
| | |
Dump of a session with more than 6 columns failed bad dump columns, since dump.zig's max_cols was 6 while a session holds MAX_COLS. It is MAX_COLS now; the limit's lines in docs/fs.md and docs/divergences.md go.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| | |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | | |
| | \ | |
| |\ \ \
| | |/
| |/|
| | | |
9P monkey
|
| | | |
| | |
| | |
| | | |
first key after it
|
| | | |
| | |
| | |
| | | |
every blank of the other panes again
|
| | |/ |
|
| | |
| |
| |
| |
| |
| |
| |
| | |
is deleted, so it can be $EDITOR
A launch inside a pane forwards its file to the session's look and returned at once, so fish's Ctrl-O (edit_command_buffer), git commit and crontab -e read their still-unedited file back and went on. With --wait, as acme's E against B and read the way plan9port's E reads acme's log, it finds the pane /index names the file by (the one already showing it, if open), follows /log on one connection with 'follow new', reads /index once more to catch a Del that came first, and then blocks with no deadline until that pane's del record: exit 0, or 1 when the connection ends with the session. The 9P client's one-shot requests keep their 2 s deadline; its new follow takes it for the setup only. Outside pardes nothing changes. --help, docs/fs.md, the README and the 9P skill say to set EDITOR='pardes --wait', which GIT_EDITOR follows. Tested in fs.py (it returns within 50 ms of the Del, a second -w waits on the same pane, one whose session is killed exits 1) and end to end: fish 4.8 in a detached session, echo hi, Ctrl-O, the waiting launch idle in poll, the line edited over 9P, Save, Del, and fish ran echo edited.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
a write to pane/new, is its error alone, and every refusal is said in words
The one-failure rule is a write's. A refused remove, pane/new's open refused for want of a slot, and an OTRUNC open's refused truncation (data's after a failed addr) also logged an err, and a reply carrying only an errno reached the client as the C library's text (Operation not permitted). tree.handle now gives such a reply Plan 9's words, chosen so 9ns maps each back to its errno (EPERM's to EACCES, as Plan 9's does), and serveFs logs errs for writes only, not a write to pane/new, which is only read. docs/fs.md and the 9P skill say so, and that a look miss quotes what was written.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
quoting what was written, and a refused placement is the look's only failure
A look at utf8txt:#3 from a terminal searched for utf8txt, missed, then found the terminal no text to address: two errs for one write. It is now looked for whole, as zzq:2 already was, so every form's miss reads no match for "<as written>". A look whose new pane was refused a place went on to settle its line in the pane it stayed on and logged has no line N after the placement failure; it now stops there.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
now say, not at the close
Round 24's no-newline rule (uwzuqzxp) already covers name, a lines file; the 9P monkey's close_runs_only_line_files repros were from a binary before it. This pins it with a test and corrects docs/fs.md, which still said such a name waited for the close.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
column's foot, not nowhere
After Delcol took the last column's panes, pane/new under Placement made a scratch that no column held, since a scratch was placed only under the asking pane, which was gone; a look from it then unwrapped the missing parent in belowParent and panicked (the 9P monkey's crash-e1873f34). Both now fall back to the foot of the active column, else the last.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
draws them
Its reference list compared \xe4\xb8 with vaxis's own gwidth, which counts the pair one cell; since qsltkuom each invalid byte is a cell, one U+FFFD each, as surface.zig draws it, so the pair is two. The unit suite failed on it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| | |
uucode joins a stray lead byte (as U+FFFD) to a following e and combining mark into one grapheme; vaxis's gwidth then counts back the replacement rune's three bytes over the one byte it stood for and overflows (gwidth.zig:62), panicking the next frame after a write of \xee e \xcc\x81 to xdata (the 9P monkey's crash-b2417c49). graphemeDisplayWidth now gives each invalid byte one cell, as surface.zig draws it, and measures the valid runs between alone.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
first step
A 9P write served before a detached host's first pump holds its batch stamped at time 0, so nextWake said to wake at 20 ms while advance, seeing the clock for the first time, set stepped_ns days later and counted due - stepped_ns back past zero: an integer-overflow panic. It was what the 64 KiB msize trial hit in fs-test (restore detached space, the connection closing at the first write's clunk), a race any msize can lose. A batch's wake is now never before the next frame.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|