Skip to content

fix(agent): name the device-state + ui-context grounding blocks in the trust clause#165

Merged
xunholy merged 1 commit into
mainfrom
fix/trust-clause-grounding-blocks
Jun 29, 2026
Merged

fix(agent): name the device-state + ui-context grounding blocks in the trust clause#165
xunholy merged 1 commit into
mainfrom
fix/trust-clause-grounding-blocks

Conversation

@xunholy

@xunholy xunholy commented Jun 29, 2026

Copy link
Copy Markdown
Owner

The / grounding blocks carry device-controllable strings (dolphin name, device_info fork/firmware, UI path) into a per-turn user message, but the trust clause named only the untrusted-* wrappers — while buildDeviceStateBlock's docstring claimed trust-clause coverage that didn't exist. JSON-escaping prevents tag breakout (so defense-in-depth, not a live hole), but the model was never told to treat the field values as data. Clause now names both blocks as read-only grounding (data, not instructions). Test proven to fail pre-fix. task ci green; eval 17/17. Found via the internal audit sweep.

…e trust clause

buildDeviceStateBlock embeds device-controllable strings into a per-turn user
message: HardwareName is the operator's dolphin name and Fork/FirmwareVersion
come from the device's device_info response (a spoofed or compromised device
controls these). buildUIContextBlock carries the current view + a file path.
Both ride inside <device-state>...</device-state> / <ui-context .../> blocks.

The system-prompt trust clause (trust_append.tmpl) named only
<untrusted-hardware-output> and <untrusted-audit-content>; it never mentioned
these grounding blocks. Yet buildDeviceStateBlock's docstring claimed "the
model is instructed via the system prompt's trust clause to treat the block as
read-only grounding" — a protection that wasn't actually wired.

encoding/json escapes <, >, & to </>/&, so injected text cannot
break out of the block tags — this is defense-in-depth, not a live breakout —
but the model was never told to treat the field values as data. The clause now
names <device-state> and <ui-context> as read-only grounding whose values are
device/operator-supplied and must never be followed as instructions, making
the docstring's claim true.

Found via the internal audit sweep.

Test: TestBuildSystemPrompt_TrustClauseCoversGroundingBlocks pins that the base
system prompt's trust clause names both blocks and the data-only instruction;
proven to fail pre-fix.

Verified: task ci green (lint 0 / vet / build / test:full 0 fail / govulncheck
clean); task eval 17/17.
@xunholy xunholy merged commit 3a132fa into main Jun 29, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant