Read the refusal instead of the status of the thing that refused #8

Merged
branderson merged 1 commits from refusal-status into main 2026-08-28 19:56:37 -07:00
Collaborator

Summary generated by LLM agent

Two commits. The first renames a cross-repository reference; the second fixes a check that called a working restriction a broken one.

The check was wrong, not the devbox

Running dejima-guard-install-key against a correctly restricted devbox reported both negative checks as NOT REFUSED, telling the operator the forced command was not in force when it was.

The two negative checks piped ssh into grep -q refused. Under pipefail a pipeline's status is the rightmost non-zero one, and a refusal is dejima-guard-shell exiting 64, relayed by ssh. So grep matched, the pipeline still came back 64, and the else branch fired. The refusal was detected and then discarded. The positive checks were unaffected because they have no pipe.

Output is captured now and tested for both halves of a refusal: the message, which is what the runbook tells an operator to look for, and a non-zero status. Neither alone separates a refusal from an ordinary failure, since cat /etc/shadow on an unrestricted key fails too, with "Permission denied" and no "refused".

A failing check also prints what the devbox actually said. The evidence that this check was wrong was sitting in output it had already captured.

Why no test caught it

The ssh stub did shift; exec bash -c "$1". For the install script that is right, but the verification calls pass options first, so $1 was the key's path and all four checks ran garbage. The phase had no behavioural coverage at all, which is how both this and the IdentitiesOnly bug before it reached a real devbox.

The stub now answers as a devbox with the forced command in place: two commands succeed, everything else gets the refusal on stderr with exit 64. Three tests cover the phase, including one asserting a devbox with no forced command still fails, so the suite cannot pass by treating everything as refused.

Tested: 47 passing. The new tests were run against both previous versions of the tool and fail on each.

**Summary generated by LLM agent** Two commits. The first renames a cross-repository reference; the second fixes a check that called a working restriction a broken one. ## The check was wrong, not the devbox Running `dejima-guard-install-key` against a correctly restricted devbox reported both negative checks as `NOT REFUSED`, telling the operator the forced command was not in force when it was. The two negative checks piped ssh into `grep -q refused`. Under `pipefail` a pipeline's status is the rightmost non-zero one, and a refusal is `dejima-guard-shell` exiting 64, relayed by ssh. So grep matched, the pipeline still came back 64, and the `else` branch fired. The refusal was detected and then discarded. The positive checks were unaffected because they have no pipe. Output is captured now and tested for both halves of a refusal: the message, which is what the runbook tells an operator to look for, and a non-zero status. Neither alone separates a refusal from an ordinary failure, since `cat /etc/shadow` on an unrestricted key fails too, with "Permission denied" and no "refused". A failing check also prints what the devbox actually said. The evidence that this check was wrong was sitting in output it had already captured. ## Why no test caught it The ssh stub did `shift; exec bash -c "$1"`. For the install script that is right, but the verification calls pass options first, so `$1` was the key's path and all four checks ran garbage. The phase had no behavioural coverage at all, which is how both this and the IdentitiesOnly bug before it reached a real devbox. The stub now answers as a devbox with the forced command in place: two commands succeed, everything else gets the refusal on stderr with exit 64. Three tests cover the phase, including one asserting a devbox with no forced command still fails, so the suite cannot pass by treating everything as refused. Tested: 47 passing. The new tests were run against both previous versions of the tool and fail on each.
dejima-agent added 1 commit 2026-08-28 19:55:30 -07:00
The two negative checks piped ssh into `grep -q refused`. Under pipefail a
pipeline takes the rightmost non-zero status, and a refusal is dejima-guard-shell
exiting 64 relayed through ssh - so grep matched, the pipeline still came back
64, and a correctly restricted devbox was reported as having no restriction at
all. The positive checks were unaffected because they have no pipe.

Output is captured and tested for both halves of a refusal: the message, which
is what the runbook tells an operator to look for, and a non-zero status.
Neither alone separates a refusal from an ordinary failure, since cat
/etc/shadow on an unrestricted key also fails.

A failing check now prints what the devbox actually said. The evidence that
this check was wrong was in output it had already captured and discarded.

The ssh stub could not have caught either this or the IdentitiesOnly bug before
it: it shifted once and ran the key's path as the command, so all four checks
ran garbage and the phase had no coverage. It now answers as a devbox with the
forced command in place, and the new tests fail against both previous versions.
branderson approved these changes 2026-08-28 19:56:24 -07:00
branderson merged commit 969d50e373 into main 2026-08-28 19:56:37 -07:00
Sign in to join this conversation.