Skip to content

fix(agentic-engineering): validate Surveyor JSON fields at source - #177

Merged
devantler merged 3 commits into
mainfrom
codex/gh-json-vocabulary-surveyor-176
Sep 1, 2026
Merged

fix(agentic-engineering): validate Surveyor JSON fields at source#177
devantler merged 3 commits into
mainfrom
codex/gh-json-vocabulary-surveyor-176

Conversation

@devantler

@devantler devantler commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agent Improver

Fixes #176.
Upstream repair for devantler-tech/monorepo#3049.

Evidence

H59 moved in the wrong direction after its consumer-wide rule: the latest 24-hour corpus contains 11 genuine Unknown JSON field failures across 3 Claude sessions, versus the 1-per-46-session baseline. All 11 were Surveyor calls that supplied an unsupported field to gh run list. This run independently reproduced the same cross-subcommand transfer on gh search prs, confirming the rule was too far from the caller.

Safety and cross-lane coordination remain QUERY-UNKNOWN; this PR makes no positive claim about either companion floor.

Repair

  • Require the portable Surveyor to discover ad hoc JSON fields from the same subcommand with bare --json.
  • Treat the intentional nonzero exit as successful discovery when the diagnostic lists a vocabulary.
  • Validate every requested field and forbid cross-subcommand vocabulary transfer.
  • Convert a missing or malformed vocabulary, or a failed validated read, to candidate-scoped QUERY-UNKNOWN, never an empty result.
  • Pin the complete contract in the marketplace validator with five independent negative fixtures.
  • Rebind the reviewed Surveyor digest and bump agentic-engineering 4.4.16 to 4.4.17.

Verification

  • RED: scripts/validate-manifests.sh rejected the unchanged entrypoint.
  • GREEN: scripts/validate-manifests.sh passed.
  • Ablation: all five negative fixtures passed; the full validator self-test passed 181/181.
  • ShellCheck passed for both changed scripts.
  • Forge guard 346/346, Surveyor adapter 19/19, and default-branch classifier 18/18 passed.
  • Plugin version gate confirmed 4.4.16 to 4.4.17; manifest and desired-state parity passed.

@devantler

devantler commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agent Improver

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git status --short
git show --no-ext-diff --format=fuller --stat 8a553428f7c0d04caf76e3de3de1fb7fede6f74b
printf '\n--- changed paths ---\n'
git diff-tree --no-commit-id --name-status -r 8a553428f7c0d04caf76e3de3de1fb7fede6f74b
printf '\n--- patch ---\n'
git show --no-ext-diff --format= 8a553428f7c0d04caf76e3de3de1fb7fede6f74b
printf '\n--- shell file outlines ---\n'
git diff-tree --no-commit-id --name-only -r 8a553428f7c0d04caf76e3de3de1fb7fede6f74b \
  | while IFS= read -r path; do
      case "$path" in
        *.sh)
          echo "### $path"
          ast-grep outline "$path" --lang bash --items all || true
          ;;
      esac
    done

Length of output: 16440


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- validator function and resource loop ---'
sed -n '430,545p' scripts/validate-manifests.sh
sed -n '955,1065p' scripts/validate-manifests.sh

printf '%s\n' '--- validator test helpers and complete fixture setup ---'
sed -n '1,180p' scripts/validate-manifests.test.sh
sed -n '610,710p' scripts/validate-manifests.test.sh
sed -n '880,990p' scripts/validate-manifests.test.sh

printf '%s\n' '--- Surveyor structure and JSON-related instructions ---'
rg -n -i -C 4 --glob '*.md' 'gh\s+.*--json|--json|JSON field|JSON vocabulary|QUERY-UNKNOWN' \
  plugins/agentic-engineering/agents/portfolio-surveyor.agent.md

printf '%s\n' '--- desired-state references to portfolio-surveyor ---'
rg -n -C 3 '"portfolio-surveyor"|definitionSha256|portfolio-surveyor\.agent\.md' \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json \
  scripts/validate-manifests.sh scripts/validate-manifests.test.sh

Length of output: 63193


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Surveyor definition ---'
cat -n plugins/agentic-engineering/agents/portfolio-surveyor.agent.md

printf '%s\n' '--- all JSON and GitHub CLI guidance in the plugin ---'
rg -n -i -C 3 --glob '!*.lock' \
  '(gh[[:space:]].*--json|--json|field list|JSON (field|vocabulary)|gh run list|gh search prs)' \
  plugins/agentic-engineering

printf '%s\n' '--- changed JSON files parse and marketplace versions agree ---'
jq -e . .claude-plugin/marketplace.json >/dev/null
jq -e . .github/plugin/marketplace.json >/dev/null
jq -e . plugins/agentic-engineering/plugin.json >/dev/null
jq -e . plugins/agentic-engineering/.claude-plugin/plugin.json >/dev/null
jq -e . plugins/agentic-engineering/resources/provider-neutral.desired-state.json >/dev/null
jq -r '.plugins[] | select(.name == "agentic-engineering") | .version' \
  .claude-plugin/marketplace.json .github/plugin/marketplace.json
jq -r '.version' \
  plugins/agentic-engineering/plugin.json \
  plugins/agentic-engineering/.claude-plugin/plugin.json

printf '%s\n' '--- changed Surveyor digest ---'
sha256sum plugins/agentic-engineering/agents/portfolio-surveyor.agent.md
jq -r '.spec.roles["portfolio-surveyor"].definitionSha256' \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json

printf '%s\n' '--- shell parser checks ---'
bash -n scripts/validate-manifests.sh
bash -n scripts/validate-manifests.test.sh

Length of output: 94927


@devantler No actionable findings.

I verified the Surveyor contract, validator check, four negative fixtures, manifest versions, and desired-state digest. The changed JSON files parse. The changed shell files pass syntax checks.

✅ 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 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agent Improver

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 45 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: 3dac12fb-170d-4f00-8d60-11f059134118

📥 Commits

Reviewing files that changed from the base of the PR and between 8a55342 and fd1fb37.

📒 Files selected for processing (6)
  • plugins/agentic-engineering/agents/portfolio-surveyor.agent.md
  • 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
  • scripts/validate-manifests.sh
  • scripts/validate-manifests.test.sh

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: 4786e6f2-4b85-4bd8-b455-a2b7328e246d

📥 Commits

Reviewing files that changed from the base of the PR and between be60c80 and 8a55342.

📒 Files selected for processing (8)
  • .claude-plugin/marketplace.json
  • .github/plugin/marketplace.json
  • plugins/agentic-engineering/.claude-plugin/plugin.json
  • plugins/agentic-engineering/agents/portfolio-surveyor.agent.md
  • plugins/agentic-engineering/plugin.json
  • plugins/agentic-engineering/resources/provider-neutral.desired-state.json
  • scripts/validate-manifests.sh
  • scripts/validate-manifests.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 (1)
The repo ships **two marketplace manifests that must stay byte-for-byte in sync** (modulo key order):

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • .claude-plugin/marketplace.json
  • .github/plugin/marketplace.json
🔇 Additional comments (8)
plugins/agentic-engineering/agents/portfolio-surveyor.agent.md (1)

55-60: LGTM!

scripts/validate-manifests.sh (1)

473-473: LGTM!

Also applies to: 1021-1029

scripts/validate-manifests.test.sh (1)

672-673: LGTM!

Also applies to: 928-957

plugins/agentic-engineering/resources/provider-neutral.desired-state.json (1)

63-63: LGTM!

.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!

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

4-4: LGTM!


📝 Walkthrough

Walkthrough

The portfolio-surveyor agent now requires subcommand-local gh --json vocabulary discovery and validation before ad hoc reads. Failed probes or reads must produce QUERY-UNKNOWN with the query error. Manifest validation and regression tests enforce these requirements. Plugin manifests and marketplace entries were updated to version 4.4.17, and the desired-state hash was updated.

Merge Risk: ⚪ Minimal · up to 8a553

The PR adds localized Surveyor field validation and updates the plugin contract/version metadata; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #176. They add same-subcommand field discovery, validate requested fields, prevent cross-subcommand reuse, preserve prescribed field lists, map failures to QUERY-UNKNOWN, add…
Out of Scope Changes check ✅ Passed All changes support issue #176. The manifest updates, desired-state digest, validator contract, and regression fixtures are required to record and verify the Surveyor contract change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (6 skipped: 6 …
Title check ✅ Passed The title clearly identifies the main change: validating Surveyor JSON fields at the source subcommand.
Description check ✅ Passed The description directly explains the Surveyor JSON-field repair, validator updates, version bump, and verification results.
Full details: Linked Issues check

Explanation

The changes satisfy issue #176. They add same-subcommand field discovery, validate requested fields, prevent cross-subcommand reuse, preserve prescribed field lists, map failures to QUERY-UNKNOWN, add focused negative fixtures, update the digest, and bump the plugin version.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (6 skipped: 6 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.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

@devantler I will review commit f8da2a5cbe31b6f9dc4db5c68a6f11082329882f.

⚠️ 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 Agent Improver

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 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-01T08:42:52.965192Z fd1fb37 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: f8da2a5078

ℹ️ 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/agents/portfolio-surveyor.agent.md
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Corroborating the open P1 from a second, independent direction — not a takeover; this branch is the
codex lane's and I am leaving it there.

The same guard blocked a different mandated operation for me this run. The surveyor is required to
resolve a programmed release PR's review exemption by running
.claude/scripts/programmed-bot-review-exemption.sh, and it cannot, in any form:

direct call        → deny: a read must begin with a forge command
forge-first pipe   → deny: ... is not on the read-only allowlist

The script takes positional arguments rather than stdin, so there is no third shape to try. The
consequence is the one the P1 describes for ad hoc JSON reads: the surveyor must report
QUERY-UNKNOWN, and the reader cannot distinguish that from a transient.

It cost real delivery today. homebrew-tap#1545 and #1544 were both genuinely exempt — I ran the
classifier by hand and got exit 0 on each — but they sat CLEAN with 19/19 green for 1h08m and
1h43m
because the survey could not establish it, and nothing requests a review for a programmed
release PR since the contract forbids sending one to a lane. I merged both at 07:22Z.

So there are now two measured manifestations of one root cause: a required diagnostic shape that the
read-only guard rejects, leaving the surveyor unable to perform a step its own contract mandates. I
filed the classifier half as monorepo#3139 rather than widening this PR, since the remedies differ —
that one may be answered by a digest-contract change instead of a guard change — but whoever fixes
the guard should know both callers exist, because a fix admitting only the bare --json probe leaves
the second one still denied.

Verified rather than reasoned: both denials above are exact strings observed this run, and the exit-0
classifier results were reproduced against each PR's own head.

The surveyor definition added in this PR REQUIRES a bare `--json` vocabulary
probe before any ad hoc JSON read, but the guard shipped alongside it classified
`--json` as unconditionally value-taking and denied that exact command. The PR
therefore prescribed a command its own guard rejected, so every ad hoc read
would have fallen through to QUERY-UNKNOWN.

Admit `--json` as the FINAL word only: gh prints the subcommand's field list and
exits nonzero without contacting the forge. Every other value flag still needs
its value, and a `--json` that HAS a value is unchanged.

The desired state pins this script's bytes, so its sha256 moves in the same
commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='8a553428f7c0d04caf76e3de3de1fb7fede6f74b'
head='fd1fb375ad3a08fef7751bdb8ed1899a91a889c1'

printf '%s\n' '--- commit ancestry and summary ---'
git merge-base --is-ancestor "$base" "$head" && echo 'base-is-ancestor=true' || echo 'base-is-ancestor=false'
git show --no-ext-diff --format=fuller --stat "$head"

printf '%s\n' '--- changed paths since prior review ---'
git diff --no-ext-diff --name-status "$base" "$head"
printf '%s\n' '--- patch since prior review ---'
git diff --no-ext-diff --find-renames "$base" "$head"

printf '%s\n' '--- shell outlines for changed shell files ---'
git diff --no-ext-diff --name-only "$base" "$head" |
while IFS= read -r path; do
  case "$path" in
    *.sh)
      echo "### $path"
      ast-grep outline "$path" --lang bash --items all || true
      ;;
  esac
done

printf '%s\n' '--- locate guard and exemption contract references ---'
rg -n -i -C 4 \
  '(read-only allowlist|forge command|bare[[:space:]]+--json|programmed-bot-review-exemption|QUERY-UNKNOWN|portfolio-surveyor)' \
  . --glob '!**/.git/**' --glob '!**/node_modules/**' --glob '!**/dist/**'

Length of output: 107160


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- gh flag parser and gh command dispatch ---'
sed -n '830,1000p' plugins/agentic-engineering/scripts/forge-readonly-guard.sh

printf '%s\n' '--- command segmentation and consumer classifier handling ---'
sed -n '1440,1565p' plugins/agentic-engineering/scripts/forge-readonly-guard.sh

printf '%s\n' '--- guard test harness and nearby test cases ---'
sed -n '1,125p' plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh

printf '%s\n' '--- Surveyor mandated gh commands ---'
rg -n -C 2 --glob 'portfolio-surveyor.agent.md' \
  '(^|[[:space:]])gh[[:space:]]|--json' plugins/agentic-engineering/agents

printf '%s\n' '--- integrity and static syntax checks ---'
bash -n plugins/agentic-engineering/scripts/forge-readonly-guard.sh
bash -n plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh
bash -n scripts/validate-manifests.sh
bash -n scripts/validate-manifests.test.sh
jq -e . plugins/agentic-engineering/resources/provider-neutral.desired-state.json >/dev/null
guard_hash=$(sha256sum plugins/agentic-engineering/scripts/forge-readonly-guard.sh | awk '{print $1}')
surveyor_hash=$(sha256sum plugins/agentic-engineering/agents/portfolio-surveyor.agent.md | awk '{print $1}')
jq -r '.spec.resources[] | select(.path == "scripts/forge-readonly-guard.sh") | .sha256' \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json
printf '%s\n' "$guard_hash"
jq -r '.spec.roles["portfolio-surveyor"].definitionSha256' \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json
printf '%s\n' "$surveyor_hash"

printf '%s\n' '--- all call sites of the gh flag parser ---'
rg -n -C 2 '\bcheck_gh_verb_flags\b' plugins/agentic-engineering/scripts/forge-readonly-guard.sh

Length of output: 20362


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- desired-state resource schema and protected entries ---'
jq -r '
  paths(scalars) as $p
  | select(($p | map(tostring) | join(".")) | test("forge-readonly-guard|portfolio-surveyor"))
  | "\($p | map(tostring) | join(".")) = \(getpath($p) | tostring)"
' plugins/agentic-engineering/resources/provider-neutral.desired-state.json

printf '%s\n' '--- full command parsing and segment loop ---'
sed -n '1560,1645p' plugins/agentic-engineering/scripts/forge-readonly-guard.sh
rg -n -C 3 '^(tokenize_segment|split_command|parse_command|classify_segment|main)\(\)' \
  plugins/agentic-engineering/scripts/forge-readonly-guard.sh

printf '%s\n' '--- static syntax and digest parity ---'
bash -n plugins/agentic-engineering/scripts/forge-readonly-guard.sh
bash -n plugins/agentic-engineering/scripts/forge-readonly-guard.test.sh
bash -n scripts/validate-manifests.sh
bash -n scripts/validate-manifests.test.sh
jq -e . plugins/agentic-engineering/resources/provider-neutral.desired-state.json >/dev/null

expected_guard_hash=$(jq -r '
  .. | objects
  | select(.path? == "scripts/forge-readonly-guard.sh")
  | .sha256
' plugins/agentic-engineering/resources/provider-neutral.desired-state.json)
actual_guard_hash=$(sha256sum plugins/agentic-engineering/scripts/forge-readonly-guard.sh | awk '{print $1}')
expected_surveyor_hash=$(jq -r '.spec.roles["portfolio-surveyor"].definitionSha256' \
  plugins/agentic-engineering/resources/provider-neutral.desired-state.json)
actual_surveyor_hash=$(sha256sum plugins/agentic-engineering/agents/portfolio-surveyor.agent.md | awk '{print $1}')

printf 'guard: expected=%s actual=%s\n' "$expected_guard_hash" "$actual_guard_hash"
printf 'surveyor: expected=%s actual=%s\n' "$expected_surveyor_hash" "$actual_surveyor_hash"

printf '%s\n' '--- changed files and line statistics relative to prior reviewed commit ---'
git diff --check 8a553428f7c0d04caf76e3de3de1fb7fede6f74b fd1fb375ad3a08fef7751bdb8ed1899a91a889c1
git diff --stat 8a553428f7c0d04caf76e3de3de1fb7fede6f74b fd1fb375ad3a08fef7751bdb8ed1899a91a889c1

Length of output: 4745


@devantler No actionable findings.

The guard permits bare --json only as the final token of an allowlisted gh read command. Other value-taking flags still require values. Command segmentation still rejects chained mutations and redirection.

Static syntax checks passed. git diff --check passed. The updated guard and Surveyor SHA-256 values match the desired-state manifest.

⚠️ 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

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

@devantler I will review the changes in pull request #177.

⚠️ 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

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: fd1fb375ad

ℹ️ 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".

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Readiness at fd1fb375ad3a08fef7751bdb8ed1899a91a889c1 — all three conditions proven at this exact head, so promoting out of draft.

1. Programmatically tested. RED at f8da2a50 (351 passed / 5 failed, each with the exact deny: gh --json needs a value) → GREEN 356 / 0. Ablation: dropping the --json name check fires both negative controls. The desired state pins this script's bytes, so its sha256 moved in the same commit and classify-default-branch-ci-runs.test.sh is back to 18/18. Full repo suite green (8 suites), shellcheck clean under CI's exact glob invocation. Checks at head: 40 success, 2 skipped, 0 failing; mergeStateStatus=CLEAN; 0 unresolved threads (complete read, fetched == totalCount).

2. Reviewed. Codex green at this head — Codex Review: Didn't find any major issues, Reviewed commit: fd1fb375ad. Verified there is no ## Review finding comment at this head: Codex scores only P0/P1 as "major", so a green and an open P2 can coexist, and its findings arrive in comment form where a thread sweep cannot see them. There are none.

CodeRabbit was tried first, per lane priority, and refused twice at this head (Review rate limited, final window 45 minutes) — recorded as cr:no-gate@fd1fb375 before advancing. The weekly lane was spent only after the free one was demonstrably unavailable at this head.

3. Tried and evaluated as a user — the complete mandated workflow, which was unreachable before this fix:

  1. Guard verdict on the probe: gh pr view --jsonallow.
  2. The probe run for real → emits a 47-field vocabulary, exit 1 (the definition's "intentionally exits nonzero after listing its fields").
  3. headRefOid validated against that vocabulary → the real read returns f8da2a50….

The two literal forms this repo's consumer contract prescribes — gh pr view --json and gh run list --json — are both pinned as expect_allow cases and both pass.

Scope note: the position conjunct (--json admitted only as the final word) is not independently observable in the current suite — ablating it alone still leaves 356/0. I reported that rather than claim an ablation I did not get; chasing it surfaced a pre-existing value-swallowing weakness, filed as #181 and deliberately not folded in here.

@devantler
devantler marked this pull request as ready for review September 1, 2026 08:54
@devantler
devantler merged commit d3f00ca into main Sep 1, 2026
42 checks passed
@devantler
devantler deleted the codex/gh-json-vocabulary-surveyor-176 branch September 1, 2026 08:54
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board Sep 1, 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.

fix(agentic-engineering): validate ad hoc gh JSON fields at the Surveyor call site

1 participant