Skip to content

Route allow-always through command authorization planner#80922

Closed
jesse-merhi wants to merge 65 commits into
mainfrom
jesse/command-auth-planner-contract
Closed

Route allow-always through command authorization planner#80922
jesse-merhi wants to merge 65 commits into
mainfrom
jesse/command-auth-planner-contract

Conversation

@jesse-merhi

@jesse-merhi jesse-merhi commented May 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the command authorization planner contract and Tree-sitter-backed POSIX planner corpus.
  • Route POSIX allowlist evaluation, allow-always persistence, approval display summaries, control-command rejection, and enforced shell rendering through the planner.
  • Remove the legacy POSIX chain/pipeline/heredoc parser from exec approval analysis; the remaining shell analyzer path is Windows-only.
  • Preserve first-miss chain behavior, safe wrapper payload handling, positional carrier guards, pipe-to-shell prompting, and strict inline-eval no-persistence behavior.

Real Behavior Proof

  • Ran a live terminal proof against this branch, outside the unit harness.
  • Command: fnm exec --using 22.21.0 pnpm exec tsx -e '<planner allowlist proof>'
  • Result: planner-rendered enforced pipeline '/usr/bin/printf' 'hi' | '/usr/bin/wc' '-c' executed through /bin/sh -lc and returned 2.
  • Result: allow-always on sh -c 'echo ok' persisted /bin/echo; a later sh -c 'id > /tmp/openclaw-parser-proof-marker' still had allowlistSatisfied: false.

Manual Validation Screenshots

Tested the planner-backed allow-always flow through the local Discord approval path against this branch.

Identical structured command reuse

echo PR80922_BASELINE was approved with allow-always; the identical rerun executed without another approval.

Identical command reuse

Changed command chain prompts separately

echo PR80922_A && echo PR80922_B did not broadly cover echo PR80922_A && touch /tmp/pr80922_changed_chain; the changed chain prompted separately.

Changed command chain prompts separately

Inline eval prompts separately

python3 -c 'print("PR80922_INLINE")' did not broadly cover python3 -c 'import os; print(os.getcwd())'; the changed inline payload prompted separately.

Inline Python eval prompts separately

Command carrier prompts separately

find ... -exec cat {} \; did not broadly cover find ... -exec wc -c {} \;; the changed -exec action prompted separately.

Find exec carrier prompts separately

PowerShell was not covered in this local pass because the test machine is macOS-only.

Verification

  • fnm exec --using 22.21.0 pnpm test src/infra/command-authorization/corpus.test.ts src/infra/exec-approvals-analysis.test.ts src/infra/exec-approvals-allow-always.test.ts src/infra/exec-approvals-store.test.ts src/infra/exec-approvals-safe-bins.test.ts src/infra/command-analysis/explain.test.ts src/infra/command-analysis/explain.lazy.test.ts src/infra/exec-approvals-parity.test.ts src/agents/bash-tools.exec-host-gateway.test.ts src/node-host/invoke-system-run.test.ts
  • fnm exec --using 22.21.0 pnpm tsgo:core
  • fnm exec --using 22.21.0 pnpm tsgo:core:test
  • fnm exec --using 22.21.0 pnpm check:changed

Copilot AI review requested due to automatic review settings May 12, 2026 06:25
@openclaw-barnacle openclaw-barnacle Bot added size: L maintainer Maintainer-authored PR labels May 12, 2026
@clawsweeper

clawsweeper Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 3, 2026, 11:49 PM ET / 03:49 UTC.

Summary
The PR routes POSIX exec allowlist evaluation, allow-always persistence, approval summaries, control-command rejection, and enforced shell rendering through a command authorization planner.

PR surface: Source +2334, Tests +2944, Docs +8. Total +5286 across 36 files.

Reproducibility: yes. from source inspection and live PR metadata: current main has the merged planner path while this PR is a conflicting older implementation of the same approval-planner direction.

Review metrics: 1 noteworthy metric.

  • Live mergeability: conflicting, maintainer cannot modify. The source branch cannot be safely landed or automatically repaired in place without maintainer action.

Stored data model
Persistent data-model change detected: serialized state: src/infra/exec-approvals-allow-always.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: superseded
Canonical: #84172
Summary: The merged planner PR owns the same central command authorization root-cause area, but this protected maintainer PR needs explicit human disposition rather than automated closure.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🧂 unranked krab
Result: blocked by patch quality or review findings.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Confirm whether any behavior in this branch is still absent from the merged exec-authorization-* planner.
  • [P2] If needed, port only that missing behavior in a narrow current-main PR and drop the stale planner namespace.

Risk before merge

  • [P1] Merging this conflicted branch unreduced would reintroduce the older command-authorization planner namespace alongside current main's merged exec-authorization-* path.
  • [P1] The touched surface decides when allow-always persists or reuses exec approval trust, so stale branch behavior can affect existing approval workflows and the exec authorization boundary.

Maintainer options:

  1. Close as superseded after maintainer confirmation
    If no unique behavior remains, close this protected PR in favor of the merged current-main planner PR and preserve this evidence in the close rationale.
  2. Port only a missing edge case
    If one behavior from this branch is still absent, reimplement only that behavior on top of current exec-authorization-* files with focused tests.

Next step before merge

  • The PR is protected and not safely repairable in place; a maintainer should decide whether to close it as superseded by the merged planner PR or request a narrow replacement.

Security
Needs attention: The branch changes durable exec approval trust and conflicts with the current-main authorization planner, so it needs maintainer security-boundary review before any landing path.

Review findings

  • [P1] Remove the superseded planner path before merging — src/infra/command-authorization/index.ts:1-4
  • [P3] Drop the release-owned changelog edit — CHANGELOG.md:4-8
Review details

Best possible solution:

Treat the merged exec-authorization-* planner as canonical, then either close this protected branch as superseded or port only a proven missing edge case in a narrow current-main PR.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection and live PR metadata: current main has the merged planner path while this PR is a conflicting older implementation of the same approval-planner direction.

Is this the best way to solve the issue?

No. The submitted branch is no longer the best merge shape because the canonical implementation now lives in current main's exec-authorization-* files from the merged planner PR.

Full review comments:

  • [P1] Remove the superseded planner path before merging — src/infra/command-authorization/index.ts:1-4
    Current main already has the merged planner under src/infra/exec-authorization-plan.ts, while this branch adds a parallel src/infra/command-authorization/* namespace. Landing both would split exec approval trust decisions between competing planners; rebase onto current main and port only any missing behavior.
    Confidence: 0.9
  • [P3] Drop the release-owned changelog edit — CHANGELOG.md:4-8
    Root policy makes CHANGELOG.md release-owned for normal PRs, but this branch adds an Unreleased entry. Keep the release-note context in the PR body or squash message and leave changelog generation to the release flow.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 9d68f877ac3e.

Label changes

Label changes:

  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body supplies after-fix terminal proof plus Discord approval screenshots showing allow-always reuse, changed-chain prompting, inline eval prompting, and carrier prompting.

Label justifications:

  • P2: The PR is normal-priority exec approval hardening/refactor work with meaningful but bounded maintainer impact.
  • merge-risk: 🚨 compatibility: The branch changes allow-always persistence and approval reuse semantics that existing exec approval workflows may depend on.
  • merge-risk: 🚨 security-boundary: The branch changes which shell commands can become durable trusted approvals and how enforced shell commands are rendered.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦞 diamond lobster and patch quality is 🧂 unranked krab.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body supplies after-fix terminal proof plus Discord approval screenshots showing allow-always reuse, changed-chain prompting, inline eval prompting, and carrier prompting.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body supplies after-fix terminal proof plus Discord approval screenshots showing allow-always reuse, changed-chain prompting, inline eval prompting, and carrier prompting.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body supplies after-fix terminal proof plus Discord approval screenshots showing allow-always reuse, changed-chain prompting, inline eval prompting, and carrier prompting.
Evidence reviewed

PR surface:

Source +2334, Tests +2944, Docs +8. Total +5286 across 36 files.

View PR surface stats
Area Files Added Removed Net
Source 20 3422 1088 +2334
Tests 15 3540 596 +2944
Docs 1 8 0 +8
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 36 6970 1684 +5286

Security concerns:

  • [medium] Stale exec approval trust-path branch — src/infra/command-authorization/index.ts:1
    The branch adds an older planner surface while current main already has the merged exec-authorization-* planner, so merging it unreduced could alter which commands become durable trusted approvals.
    Confidence: 0.86

What I checked:

  • Repository policy applied: Root AGENTS.md was read fully; its protected maintainer-item, changelog, and exec approval compatibility/security-boundary review guidance applies to this PR. (AGENTS.md:1, 9d68f877ac3e)
  • Scoped policy applied: The relevant scoped AGENTS files for src/agents and src/gateway were read; they reinforce careful gateway/agent hot-path review but do not override the root protected-item rule. (src/gateway/AGENTS.md:1, 9d68f877ac3e)
  • No maintainer notes: No .agents/maintainer-notes directory exists in this checkout, so there were no matching internal maintainer notes to apply.
  • Live PR state: GitHub reports this PR open, CONFLICTING/DIRTY, maintainerCanModify: false, and labeled maintainer, proof: sufficient, merge-risk: compatibility, and merge-risk: security-boundary. (2f43daf01c08)
  • Merged canonical planner work: The related planner PR merged on 2026-06-18 with merge commit c9707ab635b928435db4af092b01548bd2235029 and rebuilt the current exec-authorization-* implementation. (c9707ab635b9)
  • Current main planner source: Current main defines the exec authorization planner as planShellAuthorization/planExecAuthorization under src/infra/exec-authorization-plan.ts, not the PR branch's older command-authorization namespace. (src/infra/exec-authorization-plan.ts:30, 9d68f877ac3e)

Likely related people:

  • jesse-merhi: Authored this PR and the merged current-main planner PR that now owns the same exec authorization planner surface. (role: feature owner and recent area contributor; confidence: high; commits: 2f43daf01c08, c9707ab635b9; files: src/infra/exec-authorization-plan.ts, src/infra/exec-approvals-allowlist.ts, src/infra/exec-approvals.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new internal “command authorization planner” contract and a first-pass implementation that classifies commands into analyzable, prompt-only, or unanalyzable, producing a tree of command units suitable for downstream allowlist/trust evaluation.

Changes:

  • Added planner contract types (CommandAuthorizationPlan, units, tree relationships, and reason enums).
  • Implemented planCommandForAuthorization() with dialect handling and conservative prompt-only detection (inline eval, command substitution, Windows wrappers).
  • Added a corpus-style Vitest suite covering representative argv/POSIX/Windows wrapper/malformed cases.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/infra/command-authorization/types.ts Defines the planner contract types, tree structure, and reason enums.
src/infra/command-authorization/plan.ts Implements the planner and unit/tree construction logic using existing exec-approvals analyzers.
src/infra/command-authorization/index.ts Exposes the planner entrypoint and exported types.
src/infra/command-authorization/corpus.test.ts Adds corpus tests to lock in planner behavior across common command shapes and risk cases.

Comment thread src/infra/command-authorization/plan.ts Outdated
Comment on lines +52 to +53
const source = command ?? argvInput.join(" ");
const argv = argvInput.map((entry) => entry.trim()).filter((entry) => entry.length > 0);
Comment on lines +107 to +110
const source = command.trim();
if (!source) {
return unanalyzablePlan(command, "posix-shell", ["empty-command"]);
}
relationship: "wrapper-inline",
promptOnlyReasons: [reason],
});
return promptOnlyPlan(command, dialect, { kind: "unit", unitId: unit.id }, [unit]);
Comment on lines +325 to +328
if (executable === "cmd" || executable === "cmd.exe") {
return { dialect: "windows-cmd", reason: "unsupported-cmd-wrapper" };
}
if (executable === "powershell" || executable === "powershell.exe" || executable === "pwsh") {
Comment thread src/infra/command-authorization/plan.ts Outdated
command: part.part,
cwd: context.cwd,
env: context.env,
platform: context.platform,
Comment thread src/infra/command-authorization/plan.ts Outdated
Comment on lines +279 to +286
function unanalyzableFromAnalysis(
source: string,
dialect: CommandDialect,
analysis: ExecCommandAnalysis,
): CommandAuthorizationPlan {
const reason: CommandUnanalyzableReason =
analysis.reason === "empty command" ? "empty-command" : "malformed-shell";
return unanalyzablePlan(source, dialect, [reason]);
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XL and removed size: L labels May 13, 2026
@jesse-merhi jesse-merhi changed the title Add command authorization planner contract Route allow-always through command authorization planner May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot added the gateway Gateway runtime label May 13, 2026
@jesse-merhi
jesse-merhi force-pushed the jesse/command-auth-planner-contract branch 6 times, most recently from eb63177 to f95d24b Compare May 14, 2026 16:14
@openclaw-barnacle openclaw-barnacle Bot added the commands Command implementations label May 15, 2026
@jesse-merhi
jesse-merhi force-pushed the jesse/command-auth-planner-contract branch from 76666de to 68a9521 Compare May 15, 2026 04:48
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed impact:security Security boundary, credential, authz, sandbox, or sensitive-data risk. labels May 19, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 18, 2026
@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. labels Jul 4, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks @jesse-merhi. Closing this older planner branch as superseded by #84172, which landed the current exec-authorization-* planner in c9707ab. This head still adds the earlier parallel command-authorization namespace and now conflicts with current main; landing it would split the exec approval trust path. The strong proof here remains useful, but any genuinely missing edge case should be ported narrowly onto the landed planner rather than merging this branch.

@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling gateway Gateway runtime maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants