You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
emrg: the daemon-stop scan matches a signaller by token, so a read that spells both words is refused and the pipeline that really stops it is allowed #2429
emrg/tools/command_scan.py::stops_or_restarts_the_daemon classifies the act
"stop or restart the emrg daemon" in two shapes: an emrg program word followed by stop/restart, and a process signaller (pkill, killall, kill) one of
whose operands names emrg.
The signaller half matches the signaller by token, anywhere in the statement,
and then takes the next token containing emrg as its operand. It never asks
whether that token is the command being run. So a command that merely spells
both words is refused, and — in the other direction — a pipeline that really does
signal the daemon is allowed.
Measured, current tree (caf6d743), predicate driven directly
Refused, though nothing in it can signal a process:
The refusal reads: "blocked 'kill emrg/' — it stops or restarts the emrg daemon,
which is EMRG's life core". grep runs no signaller; the kill is a search
pattern and the emrg/ a path. Searching this repository for the word kill
scoped to a directory is an ordinary read.
Allowed, though it does signal the daemon:
pgrep -f emrg | xargs kill -> None
xargs is the command word here, so kill arrives as its argument, and the
operand scan looks after the signaller — where it finds nothing naming emrg.
That is a live route to the act this rule exists to prevent, and it sits on the
host's red line (MANIFESTO.md 第四条附则二).
Two more readings that fix the direction the answer must take (both correct
today, and both must stay that way):
A command that wrote a review body to a file and then posted it was refused with blocked 'kill argszero/emrg'. The body discussed a failing test in prose and
contained the word "kill"; the same command with that word replaced by "failure"
went through. The message named a pair the command never formed.
What a fix must satisfy
A signaller is the act only when it is the command word of its statement —
the first token after the previous command border (;, &&, ||, |,
newline), once wrappers in front of it are stepped over.
Wrappers count: sudo -u root kill …, nice -n 5 pkill …, env kill …, timeout 5 kill …, xargs kill … are all still the act. xargs kill is the case that is currently allowed and must become
refused.
A signaller appearing as another program's argument is not the act: grep -rn kill emrg/, git grep -n 'kill' -- emrg/tools/, grep kill argszero/emrg notes.txt are allowed.
The lifecycle-verb half (emrg server stop, emrg server restart, python -m emrg server stop) is untouched, as is the nested-text walk
(sh -c '…', eval '…', env -S '…').
Tests assert both directions, and the existing cases in tests/test_daemon_lifecycle_is_classified.py keep their verdicts — including pkill -f emrgd && ls, nice -n 5 pkill -f emrg.server, and the allowed pkill -f firefox / killall python / kill 12345.
The file's own allowed list already settles the direction
tests/test_daemon_lifecycle_is_classified.py::NOT_THE_ACT pins grep -rn stop emrg/ as a mention that must stay allowed, and it does: the
lifecycle-verb half only matches a verb that follows the program word, so a
program named after the verb is not the act.
The same command shape one word over is refused:
grep -rn stop emrg/ -> None (pinned as a mention)
grep -rn kill emrg/ -> 'kill emrg/' (refused as the act)
Both are reads. The difference is that the signaller half matches by token
anywhere in the statement, so kill as a search pattern is indistinguishable from kill as the command. That is the same over-block the file's own header cites as
the #1513 lesson (echo sh "patch /etc/hosts" was a bug, not a safe over-block),
arriving on the signaller half of the same rule.
The other direction is the one with teeth: pgrep -f emrg | xargs kill is
allowed, because xargs is the command and the operand scan looks after the
signaller. Fixing the over-block by asking "is the signaller the command word of
its statement?" closes that hole at the same time — the wrapper set has to carry xargs for exactly this reason.
Activity
how2how2how2-arch commentedon Oct 20, 2026
The file's own allowed list already settles the direction
tests/test_daemon_lifecycle_is_classified.py::NOT_THE_ACTpinsgrep -rn stop emrg/as a mention that must stay allowed, and it does: thelifecycle-verb half only matches a verb that follows the program word, so a
program named after the verb is not the act.
The same command shape one word over is refused:
Both are reads. The difference is that the signaller half matches by token
anywhere in the statement, so
killas a search pattern is indistinguishable fromkillas the command. That is the same over-block the file's own header cites asthe #1513 lesson (
echo sh "patch /etc/hosts"was a bug, not a safe over-block),arriving on the signaller half of the same rule.
The other direction is the one with teeth:
pgrep -f emrg | xargs killisallowed, because
xargsis the command and the operand scan looks after thesignaller. Fixing the over-block by asking "is the signaller the command word of
its statement?" closes that hole at the same time — the wrapper set has to carry
xargsfor exactly this reason.A patch follows, with both directions asserted.
how2how2how2-arch commentedon Oct 20, 2026
Handled by #2430