From 85d5467023a9db801d8ea2538e9611b71cd10d9d Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 04:22:56 -0300 Subject: The docs: sam gotchas, Restore's log order and paths, stream reads, layout's current and active Round 13's doc findings: a sam gotchas box in the skill ($-1 with and without a final newline, N+1 at the end, ^/$ at the end, 2,1, y's leading empty piece, c's literal &, columns from 1); the skill's Restore log order made the true one (new, restore, restored, restoredcol); a relative Restore path is looked for in DumpDir then the session's directory, and a bare one takes the last dump; a follower sees each (xN) as a new line; reading data or xdata moves addr; a second read of look/exec on one fd is EOF (re-open or seek 0); /layout's current (the keyboard's column) and active (acme's activecol) defined; no room, not no rows left; why a scratch's dirty blocks nothing under 100 bytes; the changed record listed. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/pardes-9p/SKILL.md | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to '.agents') diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md index 39f80497..2892b134 100644 --- a/.agents/skills/pardes-9p/SKILL.md +++ b/.agents/skills/pardes-9p/SKILL.md @@ -96,7 +96,7 @@ $m/pane/new open it to make a pane (a scratch named /+New), read names it empty, else taking the bottom half of its last pane (ctl `Placement pardes`: the old rules); a session holds 64 panes (16 on the board): past that, every route that opens one fails with `no space for a pane: 64 max` (ENOSPC), and so does one whose column - has no rows left (each pane keeps its tag and 2 rows: `no space for a pane in that column`); rmdir $m/pane/ closes it; a column's last pane leaves the column EMPTY + has no room (each pane keeps its tag and 2 rows: `no space for a pane in that column`); rmdir $m/pane/ closes it; a column's last pane leaves the column EMPTY (focus reads empty, the log says only del), and the session's LAST pane QUITS it $m/pane//errors write-only: text appended to the +Errors pane of the pane's directory $m/os/ the host filesystem @@ -145,7 +145,9 @@ active pane from the root and at that pane from `$m/pane//look` and made, or the pane it focused or acted on: an open's own last write's, or, on an open that never wrote, the session's last. With other clients about, write and read one open (`exec 3<>$m/look; echo x >&3; cat <&3; exec 3<&-`). -Each command line runs once whole, however a mount cuts a big write; a last +A read is a stream: once read, a second read on the same fd gives EOF (on +an open that wrote, until its next write); open again, or seek to 0, to read +it again. Each command line runs once whole, however a mount cuts a big write; a last line with no newline runs when the open closes, and an Edit block still open then fails there (an `err`, ``unmatched `{'``), changing nothing. A command that fails is reported in the editor, not as a write error, so inspect the resulting pane, index, message @@ -210,6 +212,22 @@ env printf 'Edit ,x/foo/{\ni//\n}\n' > $pane/ctl `p` and `=` print to the directory's `+Errors`. Not there: `b B D e r w f X Y`, `< | >`, and `\1`-`\9` in `s`. +> **sam gotchas** (as sam does them, pardes too) +> - `$-1` is the last line when the text ends in a newline (`a\nb\n`: `b\n`), +> but the one before it when it does not (`a\nb`: `$` is on `b`, so `a\n`). +> - A line past the end is the empty line there, not an error: `N+1` at the +> last line is `#,#`; only the line after that is out of range. +> - `^` and `$` match at the text's end too: `/^/` from the end finds the +> empty place after a final newline. +> - `2,1` is no error: it is `#,#`, an empty range at +> line 2's start (only a range whose end is before its start is refused). +> - `y` yields the stretch before the first match too, empty if the text +> starts with one: `,y/a/` on `abc` gives `` and `bc`. +> - `c/&/` puts a literal `&`; only `s` expands `&` to the match. +> - `line:col` columns count bytes from 1: `12:0` is refused +> (`a column counts from 1`); a tool's character column is the same only +> on an ASCII line. + | Operation | Shell | Python client | |---|---|---| | Read text | `cat $pane/body` | `client.read(pane + '/body')` | @@ -220,7 +238,8 @@ env printf 'Edit ,x/foo/{\ni//\n}\n' > $pane/ctl | Delete that range | `: > $pane/data` | truncate `data` (open with OTRUNC) | A write leaves `addr` just past what it wrote, so a second `echo x > data` -inserts after the first: write `addr` again before each replacement. +inserts after the first: write `addr` again before each replacement. A read +of `data` or `xdata` moves `addr` past what it read, as in acme. Truncating `data` is pardes's own (acme ignores OTRUNC and always inserts). | Read the selection | `cat $pane/dot` (offsets), `cat $pane/sel` (text) | the same two reads | | Select the addressed range | `cp $pane/addr $pane/dot` | `client.write(pane + '/dot', client.read(pane + '/addr'))` | @@ -329,12 +348,15 @@ or `line:col` inside a rune snaps back to its start, a match covers the runes it touches, and a combining mark or a CRLF's `\r` is addressable alone. A Restore puts a new editor under every client: the Restore write is answered, then every connection is hung up (their fids name the old -editor's panes); dial again, and the new log names the restored panes then -`restore ` -- the authority, since a slow client may see the cut +editor's panes); dial again, and the new log has a `new` for each restored pane, then +`restore `, then `restored ` for each pane and +`restoredcol ` for each column -- `restore ` the authority, since a slow client may see the cut before the answer. A 9ns older than cloud9 2a7137c could fail the Restore write with ECONNRESET although the Restore went ahead; trust the log. `Dump` writes `pardes--