Skip to content

fix(agentic-engineering): classify a flag-shaped word a value flag consumes - #198

Merged
devantler merged 10 commits into
mainfrom
claude/forge-guard-value-flag-classify-181
Sep 6, 2026
Merged

fix(agentic-engineering): classify a flag-shaped word a value flag consumes#198
devantler merged 10 commits into
mainfrom
claude/forge-guard-value-flag-classify-181

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agentic Engineer

Why

The surveyor's read-only guard is what keeps a survey from opening a browser, retargeting an authenticated request, or reaching a file. It consumed a value-taking flag's next word before checking it, so a denied flag placed right after any value flag was never classified at all — --repo --web read as allowed. It was not exploitable today only because gh's own parser happens to keep that word inert, a property the guard never asserted.

What

The guard now classifies the word it consumes: a flag-shaped value is refused by name unless its flag's value genuinely may begin with a dash (a search expression, a jq or template program, a git grep pattern), each justified where the rule is declared. Proven in both directions with the guard's own self-test — the swallow shapes were allowed before and are denied after, the legitimate dash-leading values stay allowed.

Fixes #181

🤖 Generated with Claude Code

…nsumes

forge-readonly-guard.sh consumed a value-taking flag's next word before checking it
against the read-only allowlist, so a denied flag placed right after any value flag was
never classified: `gh pr list --repo --web`, `--state --web`, `gh pr view 1 --limit --web`,
`gh api … -H --hostname` and `git log --since --work-tree` all read `allow`. The guard's
safety there rested on gh's and git's parsers consuming the word as an inert value — a
property the guard never asserted and that stops holding the day any value flag grows an
optional-value grammar.

Classify the consumed word itself: a flag-shaped value is denied by name unless its flag's
value grammar legitimately begins with a dash — `--search` expressions, `--jq`/`--template`
programs, git `--grep`/`-S`/`-G` patterns — each justified where the set is declared.
RED/GREEN: the five swallow shapes above allowed on the unmodified guard and are denied by
name after the change; the three dash-leading value shapes stay allowed (383/383).

Fixes #181

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
devantler and others added 2 commits September 5, 2026 18:10
…main now carries

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Readiness record — tried and evaluated as a user at dc85a34

The guard is a runtime asset with a direct user surface: forge-readonly-guard.sh --command "<cmd>". Exercised in both directions on the unmodified and the modified guard:

  • RED (unmodified guard): gh pr list --repo --web, gh pr list --state --web, gh pr view 1 --limit --web, gh api … -H --hostname and git log --oneline --since --work-tree all returned allow (exit 0).
  • GREEN (this head): each of those five is now denied, and the message names the swallowed word (consumed '--web' as its value … flag-shaped); gh pr list … --search -label:blocked, gh api … --jq -1 and git log --grep -x stay allowed, as do the surveyor's ordinary reads and the bare --json vocabulary probe.
  • Suites: forge-readonly-guard.test.sh 383/383 (the six deny-by-name and three allow cases added here included), surveyor-forge-readonly.test.sh 19/19, validate-manifests.sh clean, digests current, version gate 4.4.23 → 4.4.24 after re-basing onto the 4.4.23 base that fix(surveyor): require selection evidence before survey completion #193 moved main to. shellcheck clean.

Design note: the dash-admitting set is deliberately per flag family and justified inline — a search expression, a jq or template program, and git's --grep/-S/-G patterns can begin with a dash and can name no program, host, or file; every other value flag denies a flag-shaped word by name.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

@devantler I will review the changes in #198.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: c0507670-813a-4439-94a9-cc7a4ff56611

📥 Commits

Reviewing files that changed from the base of the PR and between 4cdc4bd and aeb4985.

📒 Files selected for processing (7)
  • .claude-plugin/marketplace.json
  • .github/plugin/marketplace.json
  • plugins/agentic-engineering/.claude-plugin/plugin.json
  • plugins/agentic-engineering/plugin.json
  • plugins/agentic-engineering/resources/provider-neutral.desired-state.json
  • plugins/agentic-engineering/scripts/forge-readonly-guard.sh
  • plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (2)
Any change to the plugin set updates both manifests in the same PR Edit both together.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • .github/plugin/marketplace.json
  • .claude-plugin/marketplace.json
README and manifests stay in lockstep.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • .github/plugin/marketplace.json
  • .claude-plugin/marketplace.json
🔇 Additional comments (3)
.claude-plugin/marketplace.json (1)

30-30: LGTM!

.github/plugin/marketplace.json (1)

30-30: LGTM!

plugins/agentic-engineering/.claude-plugin/plugin.json (1)

4-4: LGTM!


📝 Walkthrough

Walkthrough

The forge read-only guard now validates values consumed by GitHub CLI and Git options. It rejects unexpected flag-shaped values, while allowing configured search expressions, templates, regexes, dates, and numeric values. Tests cover both denied and accepted dash-leading values. The plugin version is updated to 4.4.26, and the desired-state manifest contains the new guard checksum.

Merge Risk: ⚪ Minimal · up to aeb49

The read-only guard now rejects denied flags swallowed as option values while preserving documented dash-leading inputs. Targeted coverage and synchronized release metadata indicate no remaining merge-blocking risk.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Docstring Coverage ❌ Error Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. (5 skipped: 5… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #181 by classifying consumed flag-shaped words, rejecting swallowed denied flags, preserving justified dash-leading values, and adding allow and deny tests with negative cont…
Out of Scope Changes check ✅ Passed The changes remain within scope. Script logic and tests address issue #181, while plugin version and runtime digest updates support the release of version 4.4.26.
Title check ✅ Passed The title clearly identifies the main change: the read-only guard now classifies flag-shaped words consumed as values.
Description check ✅ Passed The description directly explains the guard defect, the implemented classification rules, preserved dash-leading values, and test coverage.
Full details: Docstring Coverage

Explanation

Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. (5 skipped: 5 unsupported.)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

CodeRabbit refused this head on quota (Review rate limited), so the round advances to the next lane.

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T21:38:33.511807Z ab96548 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dc85a340b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/agentic-engineering/scripts/forge-readonly-guard.sh Outdated
devantler and others added 3 commits September 5, 2026 23:10
…er a flag

The flag-shaped-value rule denied `git log --max-count -1`, `-n -1` and `--since -1.day`,
all documented read-only git grammars, because it treated any dash-leading word as a flag.
No flag name begins with a digit, so admit `-[0-9]*` for every value flag; letters and a
second dash stay flag-shaped and denied by name. Pinned in both directions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…main now carries

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== PR diff summary =='
git diff --stat HEAD^ HEAD
git diff --name-status HEAD^ HEAD

printf '%s\n' '== Changed shell/test files: outlines =='
git diff --name-only HEAD^ HEAD | while IFS= read -r file; do
  case "$file" in
    *.sh)
      printf '\n-- %s --\n' "$file"
      ast-grep outline "$file" --items all || true
      ;;
  esac
done

printf '%s\n' '== Current-head diff =='
git diff --find-renames --find-copies --unified=80 HEAD^ HEAD -- \
  '*.sh' '*.md' '*.json' '*.yaml' '*.yml'

Length of output: 14227


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Pull request metadata =='
gh pr view 198 --repo devantler-tech/agent-plugins \
  --json baseRefOid,headRefOid,commits \
  --jq '{baseRefOid, headRefOid, commits: [.commits[] | {oid, messageHeadline}]}'

base_sha="$(gh pr view 198 --repo devantler-tech/agent-plugins --json baseRefOid --jq '.baseRefOid')"
printf '\n== Full PR diff summary (%s..HEAD) ==\n' "$base_sha"
git diff --stat "$base_sha" HEAD
git diff --name-status "$base_sha" HEAD

printf '%s\n' '== Relevant files =='
fd -a -t f 'forge-readonly-guard|surveyor-forge-readonly' plugins || true

printf '%s\n' '== Full PR guard/test diff =='
git diff --find-renames --unified=100 "$base_sha" HEAD -- \
  '*forge-readonly-guard*.sh' '*surveyor-forge-readonly*.sh'

Length of output: 53960


🏁 Script executed:

#!/bin/bash
set -euo pipefail

guard='plugins/agentic-engineering/scripts/forge-readonly-guard.sh'
state='plugins/agentic-engineering/resources/provider-neutral.desired-state.json'

printf '%s\n' '== Guard function map =='
ast-grep outline "$guard" --items all --type function

printf '%s\n' '== Value-consumption locations =='
rg -n -C 8 \
  'split_flag|VALUE_FLAGS|OK_VALUE_FLAGS|check_consumed_value|FLAG_HAS_VALUE|GIT_VALUE_FLAGS' \
  "$guard"

printf '%s\n' '== Git classifier and flag splitter =='
start="$(rg -n '^split_flag\(\)|^classify_git\(\)' "$guard" | head -n 1 | cut -d: -f1)"
end="$(rg -n '^classify_filter\(\)' "$guard" | head -n 1 | cut -d: -f1)"
sed -n "${start},${end}p" "$guard"

printf '%s\n' '== Asset digest verification =='
actual="$(sha256sum "$guard" | awk '{print $1}')"
declared="$(jq -r '.spec.source.requiredRuntimeAssets[] | select(.path == "scripts/forge-readonly-guard.sh") | .sha256' "$state")"
printf 'actual=%s\ndeclared=%s\n' "$actual" "$declared"

Length of output: 43477


@devantler Reviewed #198 at 6b9d3a67e6481c54506a7123462e5837b11d255a.

I found no issues in the reviewed change set.

The guard checks separated consumed values for gh api, gh read verbs, and git. The explicit dash-leading value exceptions are narrow. The new tests cover both deny and allow paths. The declared SHA-256 for forge-readonly-guard.sh matches the file content.

I did not execute repository scripts in the sandbox.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

CodeRabbit refused this head on quota (Review rate limited); the P2 from the previous round is fixed at this head (a dash followed by a digit is a number, never a flag) and its thread is resolved.

@codex review

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Readiness addendum at 6b9d3a6 — Codex P2 (negative numbers and relative dates after git value flags) fixed by classifying a dash-plus-digit as a value; guard self-test 387 passed, 0 failed with the three grammars pinned allowed and --since -x --work-tree pinned denied. Merged with main, re-bumped to 4.4.25, digests regenerated, validate-manifests.sh clean, CI green at this head.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b9d3a67e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/agentic-engineering/scripts/forge-readonly-guard.sh Outdated
… and date flags

`--author -bot` is a regex over authors and `--since -yesterday` an approxidate expression;
git accepts both separated forms (verified on 2.50), and the flag-shaped-value rule denied
them because only `--grep`/`-S`/`-G` were in the git dash-admitting set. Add the pattern
flags (`--author`, `--committer`) and the date flags (`--since`, `--until`, `--after`,
`--before`) with the reason stated, and move the deny controls to `--max-count`, whose
integer grammar no dash-letter word can satisfy. Pinned in both directions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Second Codex P2 (dash-leading values for git pattern and date flags) fixed at this head and its thread resolved.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@devantler have exceeded the limit for the number of chat messages per hour. Please wait 0 minutes and 33 seconds before sending another message.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='devantler-tech/agent-plugins'
pr='198'
guard='plugins/agentic-engineering/scripts/forge-readonly-guard.sh'
test='plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh'

printf '%s\n' '== Pull request metadata =='
gh pr view "$pr" --repo "$repo" \
  --json baseRefOid,headRefOid,commits \
  --jq '{baseRefOid,headRefOid,commits:[.commits[]|{oid,messageHeadline}]}'

base="$(gh pr view "$pr" --repo "$repo" --json baseRefOid --jq '.baseRefOid')"

printf '%s\n' '== Changed files =='
git diff --name-status "$base" HEAD

printf '%s\n' '== Full relevant diff =='
git diff --find-renames --unified=100 "$base" HEAD -- \
  'plugins/agentic-engineering/scripts/forge-readonly-guard.sh' \
  'plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh' \
  'plugins/agentic-engineering/scripts/surveyor-forge-readonly.test.sh' \
  'plugins/agentic-engineering/resources/provider-neutral.desired-state.json' \
  'plugins/agentic-engineering/plugin.json'

printf '%s\n' '== Guard outline =='
ast-grep outline "$guard" --items all --type function || true

printf '%s\n' '== Value parsing and classification code =='
rg -n -C 12 \
  'split_flag|classify_(gh|git)|consumed|dash|value flag|VALUE_FLAGS|OK_VALUE|is_.*number|number' \
  "$guard"

printf '%s\n' '== Relevant test cases =='
rg -n -C 4 \
  'consumed|--web|--work-tree|--since|--grep|--search|--jq|dash|flag-shaped' \
  "$test" "$test" 2>/dev/null || true

printf '%s\n' '== Runtime asset declaration =='
actual="$(sha256sum "$guard" | awk '{print $1}')"
declared="$(jq -r '.spec.source.requiredRuntimeAssets[] | select(.path == "scripts/forge-readonly-guard.sh") | .sha256' \
  'plugins/agentic-engineering/resources/provider-neutral.desired-state.json')"
printf 'actual=%s\ndeclared=%s\n' "$actual" "$declared"

Length of output: 164816


🏁 Script executed:

#!/bin/bash
set -euo pipefail

guard='plugins/agentic-engineering/scripts/forge-readonly-guard.sh'
test='plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh'

printf '%s\n' '== Latest commit delta =='
git diff --unified=80 HEAD^ HEAD -- "$guard" "$test"

printf '%s\n' '== split_flag and subcommand discovery =='
sed -n '585,685p' "$guard"

printf '%s\n' '== Full git classifier =='
sed -n '1053,1251p' "$guard"

printf '%s\n' '== Terminator and affected-value test coverage =='
rg -n -C 3 -- \
  '(^|[^[:alnum:]])--([^[:alnum:]]|$)|--grep|-S|-G|--author|--committer|--after|--before|--template|-t|--search|--jq|-q' \
  "$test"

printf '%s\n' '== Direct guard references outside the changed test =='
rg -n -C 3 -- \
  'forge-readonly-guard\.sh|GIT_DASH_VALUE_FLAGS|GH_DASH_VALUE_FLAGS|check_consumed_value' \
  plugins .github .claude-plugin

Length of output: 98686


@devantler Reviewed #198 at ab96548cb8c2256a3292ffad5aa80726b7590506.

I found no issues.

The guard classifies separated values for gh api, gh read verbs, and git options. The latest git exceptions are limited to regex, pickaxe, and date options that accept dash-leading values. The tests cover both denied swallowed flags and allowed dash-leading values. The declared runtime asset digest matches the guard.

I did not execute repository scripts in the sandbox.

You are interacting with an AI system.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

CodeRabbit answered both requests at this head as chat prompts rather than reviews (no review ran), so the round advances to the next lane. Both earlier Codex P2s are fixed at this head and their threads resolved.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab96548cb8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/agentic-engineering/scripts/forge-readonly-guard.sh Outdated
devantler and others added 3 commits September 6, 2026 04:27
…er values

A label or milestone title is a free-form server-side filter string that may itself begin
with a dash, so `gh issue list --label -bug` is a valid read the flag-shaped-value rule
denied. Add `--label` and `--milestone` to the gh dash-admitting set with the reason stated;
the host-choosing, count, state and field flags keep denying a flag-shaped value by name.
Pinned in both directions (393/393).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…main now carries

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Third Codex P2 (dash-leading label and milestone filter values) fixed at this head and its thread resolved; merged with main after #199 landed and re-bumped to 4.4.26.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='devantler-tech/agent-plugins'
pr='198'

printf '%s\n' '== Pull request metadata =='
gh pr view "$pr" --repo "$repo" \
  --json baseRefOid,headRefOid,commits \
  --jq '{baseRefOid,headRefOid,commits:[.commits[]|{oid,messageHeadline}]}'

base="$(gh pr view "$pr" --repo "$repo" --json baseRefOid --jq '.baseRefOid')"

printf '%s\n' '== Changed files =='
git diff --name-status "$base" HEAD

printf '%s\n' '== Full PR diff =='
git diff --find-renames --find-copies --unified=100 "$base" HEAD -- \
  'plugins/agentic-engineering/scripts/forge-readonly-guard.sh' \
  'plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh' \
  'plugins/agentic-engineering/scripts/surveyor-forge-readonly.test.sh' \
  'plugins/agentic-engineering/resources/provider-neutral.desired-state.json' \
  'plugins/agentic-engineering/plugin.json'

printf '%s\n' '== Relevant shell-file maps =='
for file in \
  plugins/agentic-engineering/scripts/forge-readonly-guard.sh \
  plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh \
  plugins/agentic-engineering/scripts/surveyor-forge-readonly.test.sh
do
  if [ -f "$file" ]; then
    printf '\n-- %s --\n' "$file"
    ast-grep outline "$file" --items all --type function || true
  fi
done

printf '%s\n' '== Label, milestone, and consumed-value handling =='
rg -n -C 12 -- \
  'label|milestone|check_consumed_value|consumed|DASH_VALUE|split_flag|classify_gh|--search|--jq' \
  plugins/agentic-engineering/scripts/forge-readonly-guard.sh \
  plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh

printf '%s\n' '== Runtime asset digest =='
guard='plugins/agentic-engineering/scripts/forge-readonly-guard.sh'
state='plugins/agentic-engineering/resources/provider-neutral.desired-state.json'
actual="$(sha256sum "$guard" | awk '{print $1}')"
declared="$(jq -r '.spec.source.requiredRuntimeAssets[] | select(.path == "scripts/forge-readonly-guard.sh") | .sha256' "$state")"
printf 'actual=%s\ndeclared=%s\n' "$actual" "$declared"

printf '%s\n' '== Version declarations =='
rg -n -C 2 -- '4\.4\.26|version' \
  plugins/agentic-engineering/plugin.json \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json

Length of output: 184421


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='4cdc4bdc9149acf9c27950ca450371a3c4a7c4e6'
guard='plugins/agentic-engineering/scripts/forge-readonly-guard.sh'
test='plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh'

printf '%s\n' '== Whitespace errors in full PR =='
git diff --check "$base" HEAD

printf '%s\n' '== Latest fix and version-bump deltas =='
git diff --unified=80 ab96548cb8c2256a3292ffad5aa80726b7590506 HEAD -- \
  "$guard" "$test" \
  .claude-plugin/marketplace.json \
  .github/plugin/marketplace.json \
  plugins/agentic-engineering/.claude-plugin/plugin.json \
  plugins/agentic-engineering/plugin.json \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json

printf '%s\n' '== Argument splitting and subcommand discovery =='
sed -n '587,686p' "$guard"

printf '%s\n' '== Plugin version declarations =='
rg -n -C 3 -- '"agentic-engineering"|"version"[[:space:]]*:[[:space:]]*"4\.4\.26"' \
  .claude-plugin/marketplace.json \
  .github/plugin/marketplace.json \
  plugins/agentic-engineering/.claude-plugin/plugin.json \
  plugins/agentic-engineering/plugin.json

printf '%s\n' '== Validate changed JSON files =='
for file in \
  .claude-plugin/marketplace.json \
  .github/plugin/marketplace.json \
  plugins/agentic-engineering/.claude-plugin/plugin.json \
  plugins/agentic-engineering/plugin.json \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json
do
  printf '%s: ' "$file"
  jq -e . "$file" >/dev/null && printf 'valid\n'
done

printf '%s\n' '== Guard references and asset declarations =='
rg -n -C 3 -- \
  'forge-readonly-guard\.sh|9591835448efc0d8f08f83da48deacc9a50079f4df79e9db7ed91d9146dd3649|4\.4\.26' \
  .claude-plugin .github plugins/agentic-engineering

Length of output: 71480


@devantler Reviewed #198 at aeb49857bedb01d440ffc2af8e4a49f44bbe11f7.

I found no issues.

The guard admits dash-leading values only for --label and --milestone in the gh value-grammar exception set. Other separated value flags still reject flag-shaped consumed words. The self-test adds allow cases for both filter flags.

The runtime asset SHA-256 matches forge-readonly-guard.sh. The plugin and marketplace versions are consistent at 4.4.26. All changed JSON files are valid. git diff --check found no whitespace errors.

I did not execute repository scripts in the sandbox.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devantler
devantler marked this pull request as ready for review September 6, 2026 02:35
@devantler
devantler merged commit 5004d27 into main Sep 6, 2026
41 checks passed
@devantler
devantler deleted the claude/forge-guard-value-flag-classify-181 branch September 6, 2026 02:35
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

The forge guard consumes a flag value before allowlisting it, hiding a denied flag

1 participant