Holds the v5 guard-access work, and now a prose pass ahead of going public.
Em-dashes
House style across the organisation, and the punctuation most reliably read as machine-written. The shell in this repository already used - throughout; only the prose disagreed with it. 126 of them, replaced by what each one stood in for rather than by one substitute: a colon where an explanation follows, a comma before a conjunction, brackets where a pair was fencing a parenthetical.
The blind pass corrupted the firewall table
Worth stating plainly. The rule tables use an em-dash for a cell that does not apply, so | - | - | became |: |: | in the table documenting the primary control, in both proxmox/README.md and the v2 upgrade note. Nothing about the rendered page looks wrong enough to catch on a read-through.
Repaired to ASCII hyphens, and there is now a test for table cells holding punctuation and nothing else.
Two smaller artefacts from the same pass, both at line wraps where a line-local rule cannot see the conjunction on the next line: a colon before "and", and a dash opening a line becoming a colon opening one.
The em-dash test builds the character from its bytes rather than writing it, since a check containing the thing it looks for reports itself, and the only way to make that pass is to exempt the file the check lives in.
Also in this branch, from earlier rounds
sha256sum escapes a filename containing a backslash or a newline by prefixing the line with a backslash, which broke the FILE tag, so those lines went out untagged. A watcher counts changes by their tag, so a file with such a name could change without appearing in the count the alert carries. A filename is attacker-chosen on a box under suspicion, which makes it a gap somebody could pick rather than stumble into.
And a duplicate-paragraph test, after section 3 of the node runbook was found opening with six verbatim duplicated lines, having survived two prose passes.
Tested: 180 passing. Both new prose guards were run against a reintroduced em-dash and a corrupted cell and fail on each.
**Summary generated by LLM agent**
Holds the v5 guard-access work, and now a prose pass ahead of going public.
## Em-dashes
House style across the organisation, and the punctuation most reliably read as machine-written. The shell in this repository already used ` - ` throughout; only the prose disagreed with it. 126 of them, replaced by what each one stood in for rather than by one substitute: a colon where an explanation follows, a comma before a conjunction, brackets where a pair was fencing a parenthetical.
## The blind pass corrupted the firewall table
Worth stating plainly. The rule tables use an em-dash for a cell that does not apply, so `| - | - |` became `|: |: |` in the table documenting the primary control, in both `proxmox/README.md` and the v2 upgrade note. Nothing about the rendered page looks wrong enough to catch on a read-through.
Repaired to ASCII hyphens, and there is now a test for table cells holding punctuation and nothing else.
Two smaller artefacts from the same pass, both at line wraps where a line-local rule cannot see the conjunction on the next line: a colon before "and", and a dash opening a line becoming a colon opening one.
The em-dash test builds the character from its bytes rather than writing it, since a check containing the thing it looks for reports itself, and the only way to make that pass is to exempt the file the check lives in.
## Also in this branch, from earlier rounds
`sha256sum` escapes a filename containing a backslash or a newline by prefixing the line with a backslash, which broke the `FILE` tag, so those lines went out untagged. A watcher counts changes by their tag, so a file with such a name could change without appearing in the count the alert carries. A filename is attacker-chosen on a box under suspicion, which makes it a gap somebody could pick rather than stumble into.
And a duplicate-paragraph test, after section 3 of the node runbook was found opening with six verbatim duplicated lines, having survived two prose passes.
Tested: 180 passing. Both new prose guards were run against a reintroduced em-dash and a corrupted cell and fail on each.
dejima-guard watches this box from a machine that is not this box, and it
pulls - it reaches in over SSH and the devbox never reaches out. That
inversion is what lets a guard report on a devbox that has been taken, so the
work here is one inbound pinhole and deliberately no outbound rule at all.
v5, optional, and node-side except for the key.
THE FORCED COMMAND I DOCUMENTED DID NOT WORK. It was
`command="dejima-devbox-audit ${SSH_ORIGINAL_COMMAND##* }"`, taking the last
word of whatever arrived - so `drift --state` became `--state`, which is not
a subcommand. Drift collection would have failed on every cycle while reach
kept working, leaving a box that looked watched with half of it unwatched.
Found by testing the line rather than by reading it.
bin/dejima-guard-shell replaces it: a whitelist of the two exact commands the
guard sends. Whitelisting says what may run; sanitising tries to describe
what may not, and gets it wrong quietly.
AND IT DEFAULTED TO ROOT, on a machine this project's own runbook builds
without a root password. The guard connects as an ordinary account and
elevates through sudo for those two invocations, with a sudoers line that
names both rather than the program - because NOPASSWD on the program alone
would also permit `drift --accept`, and a key that can re-baseline can tell
this box that whatever an intruder left on it is normal.
The runbook has four test commands: two that must work and two that must
print `refused`. A restriction nobody tried is a restriction nobody has, and
this one is what stands between a key taken off the guard and a shell here.
`bats test/` 171 passing, 10 new. Renumbering the guest runbook to fit §7 in
broke two anchors in the threat model, which links.bats caught.
Reported from the real box: following the note gave
sudo /usr/local/sbin/dejima-devbox-upgrade mark-node 5
dejima-devbox-upgrade: no upgrade note for v5.
and the only way through was running bootstrap, which the note never
mentions. True of that copy, not of this repository: the installed one holds
the notes it was installed with, and nothing in v5 installs newer ones.
It says to run from the checkout now, which is what the tool's own
documentation says everywhere else and what v5 should have said.
THE TEST THAT WAS MEANT TO CATCH THIS EXEMPTED IT. It asked whether a note's
`layers` mentioned the guest, on the reasoning that a guest step means
bootstrap ran. v5 has a guest step - one line in authorized_keys - and
installs nothing, so it was waved through and shipped broken.
The question was never about the guest. It is whether bootstrap runs, so the
test asks that now, and it fails on v5 as it shipped.
`bats test/` 171 passing.
Section 7 opened with a block that read guard_key.pub on the devbox. The key is
generated on the guard and never leaves it, so there is no such file there and
the first command fails for everyone who follows the section as written.
The key half now runs on the guard, via dejima-guard-install-key, which writes
the restricted line in one append rather than leaving an unrestricted key live
in the gap between copying it and adding the restriction. The sudoers half stays
here, and is done first so the guard's check does not fail on a rule that is
not yet there.
The four hand-run checks the section listed carried the same ssh -i bug the
installer had: -i adds a key to those offered rather than restricting ssh to it,
so the operator's own key authenticates, no forced command applies, and the
restriction reads as missing when it is fine.
Links in by number were fragile in the way described: the headings are numbered,
so a section inserted above this one renames it and orphans the v5 note and the
reference from dejima-guard, which is a separate repository and does not get
renumbered with it. The section carries an explicit guard-access anchor now,
and links.bats recognises explicit ids so it stays checked.
The line carried the account name of the box the runbook was written on, which
is an operator detail in a published deliverable and reads as instruction
rather than example - the next person pastes it and grants sudo to an account
that does not exist there.
sha256sum escapes a filename containing a backslash or a newline: it prefixes
the line with a backslash and rewrites the name. That broke the FILE tag, so
those lines went out untagged - and a watcher counts changes by their tag, so a
file with such a name could change without appearing in the count its alert
carries. A filename is attacker-chosen on a box under suspicion, which makes it
a gap somebody could pick rather than stumble into.
Section 3 of the node runbook opened with six duplicated lines - the primary
control, on the most-read page here, through two prose passes. A test catches
the class: a paragraph that says something correct twice reads as a
continuation to a reviewer going top to bottom, and a skimmer never sees it.
The README said "from a checkout, not the installed copy" three times and gave
the same command block twice. Once each.
House style across the organisation, and the punctuation most reliably read as
machine-written. The shell in this repository already used " - " throughout;
only the prose disagreed. Replaced by what each one stood in for rather than by
a single substitute: a colon where an explanation follows, a comma before a
conjunction, brackets where a pair was fencing a parenthetical.
A blind pass corrupted the firewall rule table. Its "not applicable" cells were
em-dashes, so `| - | - |` became `|: |: |` in the one table documenting the
primary control, and nothing about the rendered page looked wrong enough to
notice. Repaired to ASCII hyphens, with a test for cells holding punctuation
and nothing else.
Two more artefacts the same pass introduced, both at line wraps, where the
conjunction rule could not see across the break: a colon before "and", and a
dash that opened a line becoming a colon that opened one.
The em-dash test builds the character from its bytes rather than writing it,
since a check containing what it looks for reports itself and can only pass by
exempting the file it lives in.
v5's verification step said to run `dejima-guard check` and watch it succeed. A
guard with no baseline now refuses to check rather than quietly recording
whatever it finds, so following v5 verbatim on a fresh guard reports a failure
that is not one, on the step whose only job is to confirm the upgrade worked.
The note names the three commands in the order they have to run, and says why
accept comes first: a baseline taken later records whatever is on the box by
then as normal.
The install-key line runs as the guard's own account now, since the host path
gained one and that account owns the key it installs and has to read it
afterwards. The guard's README stays authoritative for that machine, and this
says so rather than growing a second copy of its setup.
A test holds the ordering. Nothing here can see the other project's code, so
what it can check is that the two commands are named in the order that works,
which is the half that goes stale silently when that project changes.
branderson
approved these changes 2026-08-29 14:10:52 -07:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary generated by LLM agent
Holds the v5 guard-access work, and now a prose pass ahead of going public.
Em-dashes
House style across the organisation, and the punctuation most reliably read as machine-written. The shell in this repository already used
-throughout; only the prose disagreed with it. 126 of them, replaced by what each one stood in for rather than by one substitute: a colon where an explanation follows, a comma before a conjunction, brackets where a pair was fencing a parenthetical.The blind pass corrupted the firewall table
Worth stating plainly. The rule tables use an em-dash for a cell that does not apply, so
| - | - |became|: |: |in the table documenting the primary control, in bothproxmox/README.mdand the v2 upgrade note. Nothing about the rendered page looks wrong enough to catch on a read-through.Repaired to ASCII hyphens, and there is now a test for table cells holding punctuation and nothing else.
Two smaller artefacts from the same pass, both at line wraps where a line-local rule cannot see the conjunction on the next line: a colon before "and", and a dash opening a line becoming a colon opening one.
The em-dash test builds the character from its bytes rather than writing it, since a check containing the thing it looks for reports itself, and the only way to make that pass is to exempt the file the check lives in.
Also in this branch, from earlier rounds
sha256sumescapes a filename containing a backslash or a newline by prefixing the line with a backslash, which broke theFILEtag, so those lines went out untagged. A watcher counts changes by their tag, so a file with such a name could change without appearing in the count the alert carries. A filename is attacker-chosen on a box under suspicion, which makes it a gap somebody could pick rather than stumble into.And a duplicate-paragraph test, after section 3 of the node runbook was found opening with six verbatim duplicated lines, having survived two prose passes.
Tested: 180 passing. Both new prose guards were run against a reintroduced em-dash and a corrupted cell and fail on each.
dejima-guard watches this box from a machine that is not this box, and it pulls - it reaches in over SSH and the devbox never reaches out. That inversion is what lets a guard report on a devbox that has been taken, so the work here is one inbound pinhole and deliberately no outbound rule at all. v5, optional, and node-side except for the key. THE FORCED COMMAND I DOCUMENTED DID NOT WORK. It was `command="dejima-devbox-audit ${SSH_ORIGINAL_COMMAND##* }"`, taking the last word of whatever arrived - so `drift --state` became `--state`, which is not a subcommand. Drift collection would have failed on every cycle while reach kept working, leaving a box that looked watched with half of it unwatched. Found by testing the line rather than by reading it. bin/dejima-guard-shell replaces it: a whitelist of the two exact commands the guard sends. Whitelisting says what may run; sanitising tries to describe what may not, and gets it wrong quietly. AND IT DEFAULTED TO ROOT, on a machine this project's own runbook builds without a root password. The guard connects as an ordinary account and elevates through sudo for those two invocations, with a sudoers line that names both rather than the program - because NOPASSWD on the program alone would also permit `drift --accept`, and a key that can re-baseline can tell this box that whatever an intruder left on it is normal. The runbook has four test commands: two that must work and two that must print `refused`. A restriction nobody tried is a restriction nobody has, and this one is what stands between a key taken off the guard and a shell here. `bats test/` 171 passing, 10 new. Renumbering the guest runbook to fit §7 in broke two anchors in the threat model, which links.bats caught.