buildRaterPrompt
buildRaterPrompt(
command,options?):object
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/shell/rater.ts:1262
Build the messages for the rater call: the system prompt (buildRaterSystemPrompt) plus a
human message that embeds the NORMALIZED command inside an XML <command_to_evaluate> tag and
(optionally) notes what a deterministic preflight already found — the script-env-leak flag,
(§4.6) a host literal in a fetch position, and ([[EXT-81]]) the shape our own parser could not
resolve. The command text is only ever DATA in the tag — the builder never executes or
interpolates it as instructions, and the notes are our own trusted text beside it. That
separation is ENFORCED rather than merely drawn: the command cannot close its own fence
(neutralizeClosingTag), so no part of it can render where our notes render.
The four preflight notes are worded differently on purpose, and the differences are the design:
- The script-env-leak note caps nothing but says “treat this as at least destructive”.
- The open-world floor note must NOT, because §4.6.1 asks the rater to upgrade a clear
typosquat to
attackand a note that anchors ondestructivewould talk it out of the one judgement it is still being asked for. It may say the command is never auto-approved, because a floor really did fire on it. - The parser note (buildParserPreflightNote) is a third register again: those two describe findings that ARE hazards and are entitled to a floor, while this one reports that our parser could not read the command, which establishes nothing about it. So it states a mechanism and asks a question, carries no verdict and no severity, and — unlike the open-world note — never says the command has already been floored, because for these families none has.
- The composed open-world note (buildComposedOpenWorldNote) shares that third register and must not borrow the floor note’s wording, for the reason the floor note is entitled to it: no floor fired here. It names the DATA FLOW across the parts rather than restating the hostname, which is already in the command text — see that function for the measurement behind that distinction.
Order matters here and is the order of a reader’s attention: FENCE_RENDERING_NOTE comes first because it is about the fenced TEXT rather than about the command and every note after it quotes or points at that text; then the two hazard notes, because each names something positively established; then the parser note, then its open-world elaboration — general shape of what could not be resolved, then the specific flow inside it.
[[EXT-127]] — the user message is now a function of the COMMAND alone. There is no round-2 form of it and no way for a caller to supply one: no justification, no transcript and no user message can reach this prompt, because there is no parameter that carries them. Every rating this builder produces is the rating of one command, which is what deliverable (a) means by “the classifier shrinks back to one job” — and it is a property of the signature rather than a discipline a caller has to keep.
§4.3 defines the rated unit tool-generally (tool name + JSON arguments); run_shell_command is
the case whose argument is a command string, and it alone is additionally normalized and
home-path-folded before fencing. The first implementation covers the shell only — every other
tool is granted or escalated by the rung without a rating call until [[EXT-30]] widens the gate.
Exposed (and returning plain strings) so tests can assert the structure: the tag is present, the untrusted-input preamble is present, and an injection string inside the command lands inside the tag rather than being acted on.
Parameters
Section titled “Parameters”command
Section titled “command”string
options?
Section titled “options?”carved?
Section titled “carved?”boolean
[[EXT-106]] (§4.6) — whether the user-provenance carve-out lifted the open-world floor on this command, decided by import(‘./provenance.js’).isOpenWorldCarved before the call.
It changes BOTH halves of the prompt, and it has to. Two places assert that the floor fired: §4.6.1’s deception guidance in the system prompt, and the open-world PREFLIGHT NOTE in the user message below. On a carved command both are false in the same direction — they tell the rater its hostname judgement is not what decides, when on this one command it is — so fixing one and not the other would send a self-contradictory prompt.
Absent is false, so every caller that does not know about the carve-out (the eval target, the unit suite’s direct calls) builds exactly the prompt it built before.
grantedTools?
Section titled “grantedTools?”readonly GrantedToolSummary[]
string
negotiable?
Section titled “negotiable?”boolean
[[EXT-29]] (§5.2) — whether a rejection will be handed back to the AGENT rather than to a person, i.e. the rung negotiates (import(‘#src/config.js’).isNegotiatingRung).
It changes the SYSTEM prompt only. The user message is a function of the command alone, so an
auto rating and an assisted rating of the same command have a byte-identical user prompt.
Returns
Section titled “Returns”object
system
Section titled “system”system:
string
user:
string