Replies: 2 comments
Second downstream use case: RTK token compression via
|
|
Confirming your three claims at the current HEAD, and adding three facts that I think change how this should be scoped. Your claims check out, verified against
Three things I would add1. The warning is deliberate and test-pinned. expect((sawArgs as { command?: string }).command).toBe('original')
expect(warn).toHaveBeenCalledWith(expect.stringContaining('updatedInput'))So honoring 2. It is not one bridge. 3. Your ask is already an acceptance criterion of the Agent Note. One vocabulary nuance, not a correction"allow/deny/ask" is the Agent Note's own phrasing ( export type PreToolDecision =
| { kind: 'allow' }
| { kind: 'deny'; reason: string; info?: ToolErrorInfo }
| { kind: 'cancel' }
| { kind: 'ask'; reason?: string }
What the RTK case changes in the designIt is the deterministic, synchronous, single-source class — no model involvement, no human decision. Three consequences:
One thing I would keep separate: honoring On validating the contractYour list — one call, parallel calls, chained transforms, permission sees only effective input, replay fidelity — maps almost onto the Note's own acceptance criteria (
Happy to validate an alpha branch against real sessions in that shape — same offer as yours. |
Uh oh!
There was an error while loading. Please reload this page.
Downstream requirements: the proposed "Pre-tool input rewrite" design
This post collects requirements from a plugin that hits the current
pre-execute ceiling every day. It references the proposed agent note
.agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.md(status: proposed; TODO(pre-tool-input-rewrite) anchors the missing phase).
The dsh-mask scenario (real, measured in our plugin workspace)
dsh-mask replaces PII with placeholders. Two of its hard rules matter here:
the agent/pre-step masking listener never blocks a step (it always calls
next()), and model-visible text equals the logged text. Its own source
records the ceiling: tool arguments cannot be rewritten at pre-execute
under the current contract, so the tools scope lands on results, "the
rewritable model-visible face" (dsh-mask index.mjs).
Consequence today: when the model emits a tool call whose arguments contain
PII (a bash command with an ID number, a key in an env assignment), those
arguments execute unmasked; masking happens only on the result content
post-execution. The only pre-execution lever tools/pre-execute offers is
allow/deny/ask over frozen arguments - for dsh-mask that means fail-closed
deny (blocks the work) or letting the plaintext run. What dsh-mask needs is
a pre-execution rewrite: replace secrets with placeholders and strip or
downgrade fields before execution, with the original arguments preserved
for audit.
Downstream view on the four open questions
Each item is a suggestion from one downstream, not a conclusion.
Q1. assistant/message rewrite vs a separate correction record.
Suggestion: default to a separate correction record carried into the next
request; keep the in-place rewrite as an explicit opt-in. Grounding:
permission-rules replays session history and keeps its decision rows
log-only, never injected into model context, precisely so the replay stays
faithful (dsh-permission-rules README). dsh-mask follows the same
invariant: the log must reconstruct exactly what the model saw. Editing the
assistant tool-call block changes what the model "sees it said"; the ADR's
own risk section notes a provider may reject that on replay.
Q2. Preserve the original arguments on tool/call (sidecar field)?
Suggestion: yes, under a reserved, schema-pinned field (for example
originalArguments). Audit needs both facts: what the model emitted and what
executed. Without the original, a post-hoc review cannot tell whether a
rewrite was the intended mask or a malicious edit, and the decision cannot
be reconstructed. Keep the sidecar out of presentation.
Q3. Where does the rewrite decision live?
Suggestion: a dedicated earlier extension point (a pre-rewrite decision)
over moving the existing pre-execute hook earlier. Moving the existing hook
forces every allow/deny/ask plugin to reason about a new ordering and can
make them run twice; a separate decision lets rewrite-only plugins such as
dsh-mask opt in while the existing gate keeps its firing point. The rewrite
must resolve before the log commit, and for deterministic maskers it should
complete synchronously without surfacing an ask.
Q4. Interaction with the permission ask flow.
Suggestion: ask binds to the effective (rewritten) arguments; the ask
payload shows the original-vs-effective difference so the human approves
exactly what will run. A decline must leave the original assistant/message
authoritative and execute nothing. A rewrite that changes the risk profile
must be visible as such, never silently folded into an approve.
What we will do with a merged mechanism
preserved; retire the post-execution-only tools scope where the rewrite
covers it.
argument forms.
back to this discussion.
All reactions