docs: rebuild README against the CLI variant template - #4
Merged
Conversation
The previous README was written against the retired single template, so it was missing the sections the current CLI variant requires and still carried three retired headings. Added: Questions this tool answers (8, weighted to platform/DevOps), a Contents block, Navigation, Reading it without a TTY, Testing across kernels, the demo section, a sample-output block, and a column-meaning table. Retired: Common use cases -> Questions this tool answers, Honest caveats -> What it can't see, Community questions -> FAQ. Reframed agent-agnostic throughout. The jail confines a process tree matched by name, and the name is a runtime knob, so nothing about the mechanism is tied to one vendor's agent. Claude Code, Codex, oh-my-pi and DeepSeek appear only as examples in the compatibility question. Documents three limits that were true but unstated: - A hardlink planted inside the jail resolves to an in-bounds path and is allowed. This is the boundary of path-based enforcement; agent-jail uses Landlock and enforces on the inode instead. Cross-linked in four places. - Confinement matches the process name and scripts/agent-lock hardcodes --comm omp, so an agent launched under its own name runs unconfined while the dashboard looks merely idle. Both workarounds are documented. - bpf must be in the active LSM list, which is set at boot via lsm=, so a kernel built with CONFIG_BPF_LSM=y can still fail to attach. Also drops a roadmap promise no issue backed, and documents that src/probes/probe.js has no import.meta.main self-test, so --headless is the only non-TTY path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
agent-lock README — reviewer notes
Rebuilt against the CLI variant template (the current one, same as
hotspot). The liveREADME was written against the retired single template, which is why it was missing
Questions this tool answers,Contents,Navigation,Reading it without a TTY,Testing across kernelsand the demo section, and why it still hadCommon use cases,Honest caveatsandCommunity questions.✅ Reviewer action items
gh repo editwill work.--audit+OMP=+--invocations in the flag examples are assembled from reading the wrapper, not run. Worth one pass on a real box.--commderivation inscripts/agent-lock(see below). It removes alooks-like-success failure mode and lets three README passages get shorter.
scripts/agent-lockandsrc/main.jsxstill call the toolagent-jailin their headercomments, and
main.jsxstill describes the retired Landlock C launcher architecture.Not README copy, but it will mislead the next reader of the source.
package.jsondescriptionstill says "with Landlock". Stale since the LSM rewrite.About description
107 characters. Leads with the category, agent-agnostic, no em-dash. (The current one is fine too;
this version drops the vendor list, which the repo description doesn't have room to keep current.)
Topic tags
Changes from what's live: add
enforcement(the category badge now claims it, and it is the axisthat separates this repo from the observe-only corpus). Drop
oh-my-pi— it is vendor-specific andworks against the agent-agnostic framing you asked for. Keep the rest.
Flagged claims
"the next thing on the list"yeet run . -- --dir ... --comm claudeworksmain.jsx:33(parsescommfromyeet.args) andfileaccess.js:41(configure(dir, comm, audit)). Read, not executed.#pragma unrollover a fixed width, and the only map write on the hot path is enrollment, which happens once per process. Stated qualitatively with no numbers, deliberately.scripts/agent-lockargument parsing, not executed.sudo -Eis included on theOMP=line because plainsudodrops the env var.demo-agent.shactually reaches for.Newly discovered limits (stated in the README, not previously documented)
Two of these are new. Per the rules skill they ship honest by default; flagging so you see what changed.
in-bounds path, so the read is allowed. This is the documented limit of path-based enforcement.
It was in commit
1a8e831's message and inadversary.shcomments but nowhere in the README.It is now in the primer, in
What it can't see, in the self-test section, and in the"why an LSM hook" trade-off, each time with the
agent-jailcross-link..dataknob and thecomm match is a single name, so a second
ompwould be enrolled against the first jail'sboundary. New FAQ entry; not previously stated anywhere.
bpfin the active LSM list is a boot-time requirement. The old README mentionedCONFIG_BPF_LSM=yand the LSM list in passing; it is now the[!IMPORTANT]callout, because akernel compiled with the option still cannot run this until
lsm=includesbpfand the machinereboots. This is the single most likely "why won't it attach" report.
src/probes/probe.jshas noimport.meta.mainblock, sounlike most yeet scripts there is no
yeet run src/probes/probe.jsone-shot. Stated plainly inReading it without a TTYwith a pointer to where it would go, per the template's rule that thesection is more useful when the answer is bad.
The
ompname requirement is a wrapper limit, not a tool limitWorth being precise, because an early draft of these notes blurred it and it is the kind of thing
that turns into "agent-lock only works with oh-my-pi" if it is stated loosely.
Three separate layers:
jail.bpf.ctarget_commis a patchable.dataknob. No compiled-in name.src/main.jsx+fileaccess.jsmain.jsx:33readscommfromyeet.args;configure(dir, comm, audit)patches whatever it is given.yeet run . -- --comm claudeworks today (verified by reading both call sites).scripts/agent-lock--comm omp, andOMP=only selects which binary to launch, not what name it is matched under.So the only thing pinning
ompis one hardcoded flag in the shell wrapper. The README now saysexactly that, adds a
### Launching a differently-named agentsubsection with both routes (asymlink plus
sudo -E, or driving the script directly with--comm), and keeps the failure-modewarning: a name that was never enrolled runs unconfined, and an empty dashboard looks identical
either way.
The fix is roughly one line. Derive the comm from the launched binary in
scripts/agent-lock:That would let the README drop the workaround entirely. Two things to decide while you are in there:
matching by name also confines any unrelated process sharing that name (matching the launched pid
instead would be tighter), and a bare
--common a common name likenodewould be a wide net.Also worth knowing
⊟ JAILED/⚠ AUDIT · UNCONFINEDmasthead badges are ALL CAPS, which violates theno-ALL-CAPS rule (
feedback_no_all_caps). That is UI code (src/components/header.jsx), notREADME copy, so I did not touch it; the README's sample output shows them in sentence case as
jailed/audit · unconfined, which is where they should end up. Smallheader.jsxfix.discord.gg/dYZu9PjKB; the corpus footer and every otherrepo use
discord.gg/JxVseaAVAU. This draft usesJxVseaAVAU. Confirm that's the right invite.assets/agent-lock.gif, 1.7 MB) with a rewritten alt text. Ifthe masthead caps get fixed,
scripts/demo-record.shregenerates it..github/workflows/kernel-matrix.ymlis present, so no CI finding. There is noveristat-matrixmake target though, despite the template describing one; the README documentsonly
make veristat, which does exist.Machine-readable handoff