-
Notifications
You must be signed in to change notification settings - Fork 2
plat 124
| Coordination | Value |
|---|---|
| Assigned agent | unassigned |
| Ticket state |
implementation repaired; live reverify pending — the read grants shipped, but a 2026-08-21 Linux run proved the granted bridge spill directory was not created before Landlock compiled the policy |
| Last synchronized | 2026-08-21 |
-
Priority: P1 — on Linux, a fresh workflow without
tool_output_foldercannot initialize the sandbox, so both shell and browser execution fail before the step can read inputs or produce outputs. -
Owner:
pkg/browser/executor.go(snapshot inline cap),controller_message_sequence.go+controller_agent_factory.go(folder guard read paths) -
Related: PLAT-073) cluster F (
dd9ede3c) grantedtool_output_foldertosetupExecutionFolderGuardfor exactly this reason; the two parallel guard builders were never updated and nothing pinned the parity.
Confirmed live 2026-08-17, workflow confida-login, group confida-staging,
step execute-browser-and-capture-apis.
1. The snapshot cap discarded the evidence. maxInlineSnapshotOutputRunes
is 24000. Four snapshots came back at ~30,365 runes — 26% over. The handler
returned ("", err):
SNAPSHOT_RESULT_TOO_LARGE: agent-browser returned 30365 runes (30365 bytes),
exceeding the 24000-rune inline safety limit. ... No snapshot content was
returned inline ... Retry deliberately with --selector <css> ... or --depth <n>
The tree was thrown away. The agent then had to guess a CSS selector for a page it had not been allowed to see, on a step where turns were already the binding constraint.
2. The spill it was pointed at was unreadable. Separately, when a bridge
tool result passes its inline cap, mcpbridge persists the full output to
MCP_TOOL_OUTPUT_DIR (<workspace-root>/tool_output_folder) and returns
"full output saved to: <path>". But this step's folder guard granted:
read=[.../execution, soul, builder, db, knowledgebase, learnings/_global,
learnings/execute-browser-and-capture-apis, ~/Downloads]
No tool_output_folder. So the agent was handed a path it was forbidden to
open, and got the dead-end:
access denied: <...>/tool-results/mcp-api-bridge-agent_browser-<n>.txt is a
truncated tool-result spill written by your coding CLI, outside every workspace
root. It cannot be read, and no workspace-relative path points at one.
setupExecutionFolderGuard had granted tool_output_folder since PLAT-073
cluster F, and its comment names "a large agent_browser snapshot" as the
motivating case. But setupMessageSequenceFolderGuard and
setupKBUpdateFolderGuard are separate parallel implementations that never
received it. Measured across the run: every msgseq-* session lacked it; only
session-group-* and generic sub-exec-eval-* sessions had it.
Video Studio's shortform-script message-sequence step failed before reading
its valid shortform-brief.md dependency. Both execute_shell_command and
agent_browser returned SANDBOX_UNAVAILABLE (missing tool_output_folder).
The workflow root had no tool_output_folder because mcpbridge previously
created it lazily only when an oversized result was first persisted.
The folder-guard parity repair above was therefore necessary but insufficient: Landlock compiles its ruleset before the first bridge call and correctly refuses to authorize a nonexistent path. A read grant cannot create its own target.
The shared repair belongs in mcpagent, where MCP_TOOL_OUTPUT_DIR is owned.
buildBridgeMCPConfig now creates the directory with mode 0700 when assigning
the environment variable, before any coding CLI or guarded tool can run. Setup
fails with a contextual error if the directory cannot be created; the sandbox
continues to fail closed rather than silently dropping the grant. Tests prove
both creation and the failure case. Live acceptance requires retrying the
Video Studio script step after deploying the rebuilt agent binary.
The cap's own comment is the constraint any fix must respect:
"Snapshot output above this threshold must fail explicitly rather than being silently narrowed or truncated: the agent, not the runtime, chooses which evidence surface to inspect next."
That is a real correctness hazard, not defensiveness. A silently truncated
accessibility tree is indistinguishable from a page where the element is
genuinely absent — and a QA step that records "control not found" from a cut-off
tree files a false negative. Raising or removing the cap is also wrong: ~30k
runes is ~7.5k tokens, and this session made 290 agent_browser calls; the cap
is doing real work on context.
So the fix keeps the principle and changes only what happens at the cap.
Snapshot handling (handleOversizedSnapshot, replacing
snapshotResultTooLargeError):
- Return the first 24000 runes behind an unmissable banner —
SNAPSHOT_TRUNCATED+ "THIS TREE IS INCOMPLETE. An element missing from the text below may still exist on the page — do NOT record it as absent" — so the false-negative hazard is addressed by being louder, not by withholding. - Offer three explicit next moves:
--selector,--depth, or--full-snapshot. -
--full-snapshotis a new AgentWorks-level opt-in (stripped before the CLI runs, sinceagent-browserwould reject it as an unknown subcommand). It returns the whole tree inline, letting the agent knowingly pay the context cost — the same "agent decides" principle the cap was written to protect. Anything past the bridge's own 128KB result cap is spilled and is now readable.
Folder guard: granted tool_output_folder (read-only) in
setupMessageSequenceFolderGuard and setupKBUpdateFolderGuard, matching
setupExecutionFolderGuard.
Tests: TestOversizedSnapshotReturnsTruncatedHeadWithIncompletenessBanner,
TestFullSnapshotFlagReturnsWholeTreeAndIsStrippedFromCLIArgs, and
TestEveryFolderGuardBuilderGrantsToolOutputFolder — the last one pins parity
across all three builders so this class of drift fails a test next time.
-
The three guard builders remain three implementations.
tool_output_folderis now consistent and pinned, butsetupMessageSequenceFolderGuardstill omitsplanning/and the run folder thatsetupExecutionFolderGuardgrants — each for a documented reason (a step judging its own scope; a CDP step that "burned four calls" walking to its own output path). Whether message_sequence steps should have those too was not decided here. Consolidating the three into one builder with explicit per-caller options is the real repair. -
--full-snapshothas had no live exercise. Unit-tested only; no real browser run has requested it yet.
- An oversized snapshot returns usable tree content plus an explicit incompleteness banner, and never costs a blind retry.
- A step that receives
"full output saved to <path>"can read that path, from any of the three guard builders. -
--full-snapshotreturns the complete tree and never reaches theagent-browserCLI as an argument. - Verified on a live browser run, not only by unit test.
Auto-synced from docs/ on main. Edit there, not here.