Skip to content

Single-line quoted free-text args still inflate stored approval patterns #1406

Description

@Aaronontheweb

Context

Follow-up to #1402, which made multi-line quoted arguments a termination condition for shell approval pattern extraction. That fix keys on the symptom (an embedded line break) rather than the underlying category (quoted free-text content is call-specific), so the single-line variant of the same bug remains.

Problem

A single-line quoted message body flows verbatim into the stored pattern — neither existing termination rule fires:

freshdesk ticket reply --message "Single line body"

Current stored pattern:

freshdesk ticket reply --message Single line body

Every unique body becomes a new pattern — the same bloat class as #1402, minus the newline. Approve-once retry keys are overly specific, and the prompt's pattern line carries call-specific content.

Note: the digit rule masks this for many real invocations (freshdesk ticket reply 605 --message "..." terminates at 605), so the bug only manifests when no digit-bearing token precedes the quoted arg.

Possible approach

ShellSyntaxTree.Arg.Raw preserves outer quotes (the SummarizeMultilineArg helper added in #1402 already sniffs them), so quoted args are structurally detectable without package changes. Two candidate predicates, from narrower to broader:

  1. Whitespace-containing arg — an unquoted arg cannot contain whitespace, so Raw containing a space proves it was quoted free text. Catches "Single line body" but not "fix".
  2. Any quote-leading arg — catches single-word quoted values too (git commit -m "fix"), but quoted and unquoted variants of the same command would then normalize differently (git commit -m fix keeps the operand, git commit -m "fix" drops it).

Why this needs design discussion (deferred from #1402)

This is a behavior change with grant-semantics implications, not a pure bug fix:

  • git commit -m "fix the bug" would normalize to git commit -m — pattern-store consumers and any tests pinning current normalization need review.
  • Quoted globs and patterns are arguably invocation intent, not free text: find . -name "*.cs", grep "foo bar" file. Dropping them may be fine (they are call-specific) but should be a deliberate choice.
  • The spec's "Shell command pattern matching" requirement (openspec/specs/tool-approval-gates/spec.md) currently defines call-specific classification as "one morphological rule" (digit-bearing); adding a quoted-content rule should be reconciled with that framing rather than bolted on.

Affected code

  • src/Netclaw.Security/IToolApprovalMatcher.csReconstructClauseText(), IsCallSpecificValueToken()
  • openspec/specs/tool-approval-gates/spec.md — "Shell command pattern matching" requirement

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions