Skip to content

The tool-argument injection documents three rules and applies five #2481

Closed

Description

@argszero

EmrgServer._inject_tool_arguments (emrg/server/daemon.py) opens its docstring with
"Three rules." and then enumerates exactly three: the session cwd pinned for the shell
tools, the same cwd as a default for the read-only discovery tools, and the sandbox
tier. The function body writes nine keys in five classes:

class keys what the docstring says
shell cwd workdir bullet 1
discovery default workdir, path bullet 2
tier sandbox, workspace bullet 3
writable roots writable_roots nothing
delegation parent _parent_session_id, _parent_cwd, _parent_tools, _parent_sandbox nothing

The two undocumented classes are the ones that exist because a caller must not choose
the value
:

  • writable_roots is injected unconditionally into _ROOT_CONSUMING_TOOLS, and
    emrg/server/daemon.py:4343 carries the whole argument — a list of roots has no
    neutral value, so an honoured model-supplied list would be a sandbox whose boundary
    the sandboxed decided.
  • The four _parent_* keys derive a delegated child's slot and give it this turn's
    tool set and tier, so that a round which may not use a tool cannot hand it to a
    session it spawns, and so that a child cannot run at a tier the model named for it.

Why it matters. The docstring is the map a reader uses to audit what the daemon
overrides in a tool call it did not write, and it is the only such map — the two
classes it omits are precisely two ways out of the sandbox. A reader who trusts the
enumeration concludes that a call's writable roots and a child's tier come from the
model, which is the opposite of what the code does. Nothing measures the enumeration:
grep -rn "Three rules" tests/ answers nothing, so the prose has been free to drift
while every behavioural test stayed green.

What the fix must satisfy.

  1. The docstring's enumeration names all five classes, in the file's own voice, and
    names each key it writes.
  2. A test derives the injected keys from the function itself rather than from a
    hand-written list, and fails when a key is written and not documented. Pinning the
    derived set exactly keeps the producer honest in both directions: a key added to
    the code without a sentence fails, and so does a bullet left behind for a key the
    code no longer writes.
  3. The guard is shown to redden in both directions (a key dropped from the prose; a
    key added to the code), with the mutated line printed before the run.

Activity

  1. argszero commented on Oct 22, 2026

    @argszero
    OwnerAuthor

    Handled by #2482

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions