Catalog/P family/P21
Proposed specificationSource-located exemplarH2

Syntax-aware command permissioning

Inspect command structure before execution.

JOIN POINTcommand_authorization_boundaryRECORD STATUSCandidate · v0.1.0
UML class view for Syntax-aware command permissioning, showing participant roles, received calls, and analytical dependencies
FIG. P21 / UML CLASS VIEW
Object interaction diagram for Syntax-aware command permissioning, showing role collaboration and a numbered message sequence
FIG. P21 / OBJECT INTERACTIONS
Context
An agent proposes a shell command with security-relevant structure.
Trigger
The command is about to be parsed, classified, or executed.
Structure
Shell parser, normalized command tree, policy evaluator, and execution handoff.
Effect
Authorization uses parsed operations and a parse failure cannot fall through to execution.
Requires
The command is representable by a parser or rejected before execution.
Ensures
Every subcommand and redirection is covered by a policy decision.
Invariant
Parsed intent and executed command refer to the same normalized operation.
Violation
Unsupported syntax fails closed or requests explicit review.

Negative control

A substring denylist is not syntax-aware permissioning.

Permitted variation

Tree-sitter or shell AST, policy language, command aliases, and escalation.

Test obligation

Test pipes, substitutions, quoting, malformed input, and policy bypass attempts.

Evolution question

Did policy move from string matching to parsed operation boundaries?

PROMPT SKETCH
Parse shell commands before execution. Every subcommand, pipeline stage, and redirection must receive a policy decision; if the command cannot be parsed, reject it rather than guessing.
CODE DESIGN / PYTHON
def authorize(command, policy):
    try:
        tree = shell_parser.parse(command)
    except ParseError:
        return Decision.deny("unparseable command")
    decisions = [policy.decide(node) for node in walk(tree)]
    if any(decision.denied for decision in decisions):
        return Decision.deny(decisions)
    return Decision.allow(decisions)

Illustrative design sketch. String matching on the full command cannot cover every nested effect. This example is a teaching aid, not implementation evidence or a conformance claim.

Join point
command_authorization_boundary
Source locator
Barbaste et al., §10.9, p. 39 (OpenCode); Table 12 “Syntax-Aware Command Permissioning”, p. 53; source label
Lexical cue
(?i)\b(?:shell[_-]?pars|command[_-]?pars|bash[_-]?pars|syntax[_-]?aware|authorize[_-]?command)\bFrozen expression, v0.1.0. A match is a retrieval cue, not a confirmed implementation.
Aliases
shellparse, commandparse, syntaxaware, authorizecommand
Canonical exemplar
OpenHands/software-agent-sdkopenhands-sdk/openhands/sdk/security/shell_parser.py:58Support: tests/sdk/security/test_shell_parser.py:1
Negative control
A substring denylist is not syntax-aware permissioning.

Scope-anchored review. pohe-agent analyze <repo> --pattern P21 anchors the cue to its enclosing declaration and checks a separate operational signature for all four pointcut dimensions. Missing roles and negative-control risks remain visible; a structural match is not E2/E3. Calibration report ↗

Source-located exemplar

A concrete source anchor is available for this proposed record. It is one exemplar, not evidence that all repositories—or every contract field—conform.

Review boundary: this candidate and its specification come from an AI-assisted study. Independent human validation remains open.

ANY-EVIDENCE FAMILY COVERAGE2/36

5.6% of repository families in the frozen panel have at least one current cue, historical cue, or canonical source layer. This is not confirmed prevalence.

Current lexical-cue repositories: 1 / 41
Canonical source anchorOpenHands/software-agent-sdk 5c524ad65d81openhands-sdk/openhands/sdk/security/shell_parser.py:58

Tree-sitter shell parse before policy evaluation.

Exploratory retrieval cue Regex / v0.1.0
(?i)\b(?:shell[_-]?pars|command[_-]?pars|bash[_-]?pars|syntax[_-]?aware|authorize[_-]?command)\b

This expression is a discovery instrument only. A match is a retrieval cue—not a confirmed implementation, pointcut match, or contract proof.