A record of a review, kept as it stood; what it found is fixed in protocol-v1.md or listed there under Open.
Two readers reviewed docs/protocol-v1.md at 13c00acc76, each given only the documents: a fresh reader (contradictions, gaps, words, KEEP.md), and an implementer asked to design a node from the draft alone. Together they made about 60 findings, many the same. Each is listed here once, with what the revision did.
| Finding | Revision |
|---|---|
The echo example is refused by the draft itself: cwd defaults to {workspace}, which a run without a workspace never sets |
cwd defaults to / without a workspace, and a default naming a value not set is left out, not refused |
{name} cannot be told from literal text such as JSON; no escape |
values are written $$name$$, the maintainer's suggestion, so { and a shell's ${HOME} stay literal and no escape is needed |
Which strings take values was unstated; {user} in process.user would be circular |
listed: every string of workspace, sandbox and process but user, when, deliveries, hears, checkins; never keys |
{release} mounted in the example is one of the node's own files, which are refused |
the own files are a table, with {release} and {workspace} allowed by name |
run was in the envelope and also "beyond" it; a run message has none |
the envelope carries run in every kind but run; each kind lists all its fields |
| "Newest version" and "edits ignored" disagreed | a message is read from the first version; an edit is ignored |
| The echo's output never reaches Fossil (KEEP: processes "that end up with writes to Fossil") | keep.stdout_when takes always, and the echo example uses it |
| Kept logs: no file names, no post format, nothing without a workspace | section 8.2: file names, a plain reply with fenced stderr and stdout blocks and the exit, rewritten per process |
| "The node holds no state of its own" was false | section 4 lists what the node keeps and why |
| A run arriving twice would remake its workspace and be refused | directory removes what was there; a run in the node's care is acted on once |
| No row for a hand run refused when it is started | refusals are checked at arrival and at start, with a state-table row |
| When "not in its care" is checked was unstated | at the node's start and whenever its administrator runs the check again; care begins before the workspace |
terminal false against a hand run joining a terminal |
attach joins a terminal only; run starts a hand run |
deliveries: start left the first line, terminals and logs per process open |
each process reads the first line, its delivery, then end of input; a terminal each; logs rewritten each; the session ends on a stop or past wall |
| Delivery lines had no artifact hash; check-ins no comment | hashes, and the check-in's comment, added |
| Key-only braces were not JSON | notation defined at the top |
| Sandbox fields had no defaults | every sandbox field is required |
ends_with_node named an undefined process |
the node's process that watches the run |
| Which account runs the process was unstated | the node's own account, the sandbox's uid inside it |
| A fresh password per run breaks the same user's other runs | the server's node runs one run at a time for each user, stated |
clone silently needed password |
a Needs column; refusal row 3 covers an unmet need |
A clone node refused even runs with no password step |
row 6 applies only to a run with a password step |
| "A person's" user: no way to tell | removed |
How command[0] is found |
on env's PATH, unless it holds / |
ended's outcomes, exit for a signal and note were scattered |
section 12, one table |
When wall starts; size forms; units |
a "Counted from" column; one size form, 1024-based |
"Names no program" yet timeout and ulimit named |
the limits table says what enforces each, on Linux |
{project} differs per node |
the server's repository's name |
| "Works for" undefined | the first run an admin or setup sent with that process.user, whatever became of it |
| "Tool" clashed with GLOSSARY.md; new words unapproved | tool became step; section 13 lists every new word for the maintainer |
| Jargon: "namespace", "capabilities" against Fossil's, "counts" | plain words; Linux capabilities marked "not Fossil's"; "counts" points to section 3 |
| Prose that should be rows: substitution, ignored or refused, own files, report placement | each is a table |
env and the budget moved out of the approved sandbox (62e45fcde6) without the maintainer's word |
listed as an open amendment for the maintainer |
memory by "a cgroup (not yet)" read as optional |
a node refuses it until it enforces it |
cpu budget against another kill |
SIGXCPU marks it |
| Mount order for overlapping paths | the sandbox table's order, a later field over an earlier one |
Duplicate started or ended; unknown kinds |
the first in the server's order counts; an unknown kind is ignored |
Left for the maintainer: the words of section 13, the amendment of 62e45fcde6, and the items under "Open".