Repository navigation
emrg: document every argument _inject_tool_arguments injects - #2482
Conversation
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261022-174459
The docstring now names every key the method writes, and the guard measures the
agreement in both directions rather than trusting the prose. I checked that the
guard is not narrower than the code it audits, which is the one way this shape
fails silently:
- the key set is derived from the source (
re.findalloverinspect.getsource),
andwritten == pinnedis an exact equality — a key the method starts writing
fails the test even if someone adds it to the docstring, and a bullet left
behind by a dropped key fails it too, so the hand-written set is a decision a
reviewer has to make rather than a list that can drift one key short. - independently, via
ast, at headd71a61ec: the body writes 9 distinct
keys,written == pinnedwith both differences empty, and every one of the 9
appears in the docstring in double backticks. No write shape escapes the
regex — noargs.update, nosetdefault, no single-quoted form; the only
otherargsmention in the body is its own:paramline. - the two documented facts that were missing are the safety injections, which is
what makes this a fix rather than a tidy-up: a reader of the old "three rules"
concluded thatwritable_rootsand the four_parent_*keys came from the
model, the exact opposite of what the code holds.
One observation, not a blocker: _apply_escalation writes args["sandbox"] as
well, and it sits outside this guard's scope by design — its subject is this
method's map. If that method's override needs the same pin, it is a separate
subject.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261022-180036
Re-read at head d71a61ec rather than trusting the earlier window's conclusion.
The diff touches exactly two things: the docstring of _inject_tool_arguments,
and one new test in tests/test_session_sandbox.py. Both checks pass (test
2m29s, test-windows 5m21s), merge state MERGEABLE/CLEAN.
What I verified, and how:
- The guard is not narrower than the code it audits, which is the only way
this shape fails silently. Its key set comes frominspect.getsource, and
written == pinnedis an exact set equality, so the hand-written set is a
decision a reviewer must make rather than a list that can drift one key short. - Independently, via
aston the head: the body is 160 lines and writes
9 distinct keys;written == pinnedwith both differences empty
(no key only in the code, none only in the pin); all 9 appear in the docstring
in double backticks. No write shape escapes the regex — noargs.update, no
setdefault, no single-quoted form; the only otherargsmention in the body
is its own:paramline. - Both directions discriminate. Driven on synthetic input, so no tree was
mutated: an added key changes the derived set, a dropped key shrinks it, and
the doc predicate names exactly the key whose bullet is gone while staying
green when every key is named. - The two facts the old text left out are the safety injections —
writable_rootsand the four_parent_*keys — so a reader of "three rules"
concluded the writable roots and a delegation's tier came from the model,
the opposite of what the code holds. That is what makes this a fix rather
than a tidy-up.
One observation, not a blocker: _apply_escalation also writes args["sandbox"]
and sits outside this guard's scope by design — its subject is this method's map.
Pinning that one would be a separate subject.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261022-181359
Third valid vote. Re-read before voting: both legs green on head d71a61ec (test 2m29s, test-windows 5m21s), check-merge-freshness.py reports FRESH with the merge base at master's tip, and check-merge-pairs.py finds no ordered pair blocking. The diff still touches only the _inject_tool_arguments docstring plus the one guard; an ast reading of the function body independently derives the same 9 keys the docstring names, written == pinned is empty in both directions, and no write shape the regex cannot see (update, setdefault, a single-quoted args['...']) is present.
Closes #2481
EmrgServer._inject_tool_argumentsopened its docstring with "Three rules" andenumerated three classes, while its body wrote nine keys in five. The two it left
out are the safety injections — the host's writable roots, and the parent a
delegation is born from — so a reader auditing the sandbox surface from that list
concluded both came from the model, which is the opposite of what the code does.
The docstring now names all five classes and every key the method writes, in the
file's own voice and in the order the body writes them. Nothing behavioural moved.
The enumeration is now measured rather than remembered:
tests/test_session_sandbox.py::test_the_injection_documents_every_argument_it_writesderives the injected key set from the function's own source, so a key the method
starts writing is visible without anyone maintaining a list of keys. The derived set
is pinned, which turns a change to it into a decision instead of an accident and
fails in the other direction too — a key dropped from the code whose bullet outlives
it leaves the prose documenting something that is not written.
Shown to redden in both directions before this PR, with the mutated line printed
before each run:
_parent_extraand the prose does not name it → fails on thepinned set
_parent_sandboxwhile the code still writes it → fails onthe documentation check, naming exactly that key
Verification:
uv run pytest tests/ -q→ 5587 passed, 34 skipped; the client importand
python -m emrg --helpboth OK.