Skip to content

[codex] Add host adapter and Codex plugin metadata - #73

Merged
justin808 merged 5 commits into
mainfrom
codex/awf-b3-host-adapter
Jul 4, 2026
Merged

[codex] Add host adapter and Codex plugin metadata#73
justin808 merged 5 commits into
mainfrom
codex/awf-b3-host-adapter

Conversation

@justin808

@justin808 justin808 commented Jul 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds the portable Host Adapter Contract and identical-text ADR for Codex/Claude shared skill text.
  • Applies installed-skill helper/reference path-resolution wording across affected skills and workflows.
  • Adds Codex native plugin manifest metadata, OpenAI picker metadata, host-syntax linting, manifest validation, and install/status fixture coverage.

Closes #42
Closes #58
Closes #36
Closes #60
Closes #43

QA Evidence

Batch Split State

Merge Authority

merge_authority: ask. Not merged.

Summary by CodeRabbit

  • New Features

    • Added Codex plugin metadata support so the pack can be consumed as a native plugin.
    • Added new validation commands for plugin metadata, host-adapter syntax, and OpenAI agent metadata.
  • Bug Fixes

    • Strengthened checks to catch invalid skill paths, missing skill files, and unsupported prompt content.
    • Improved install validation to ensure the right assets are written for each host path.
  • Documentation

    • Expanded setup and upgrade guidance for Codex native plugin usage and host installer options.
    • Added host adapter contract and installation policy documentation.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@justin808, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3839a732-59e5-4db5-a66b-c90943df626d

📥 Commits

Reviewing files that changed from the base of the PR and between bbb3fbf and 33343f5.

📒 Files selected for processing (20)
  • bin/codex-plugin-manifest-check
  • bin/codex-plugin-manifest-check-test.rb
  • bin/host-adapter-syntax-test.rb
  • bin/validate
  • bin/validate-host-adapter-syntax
  • bin/validate-openai-agent-metadata
  • bin/validate-openai-agent-metadata-test.rb
  • skills/address-review/SKILL.md
  • skills/adversarial-pr-review/SKILL.md
  • skills/adversarial-pr-review/agents/openai.yaml
  • skills/autoreview/SKILL.md
  • skills/plan-pr-batch/SKILL.md
  • skills/post-merge-audit/agents/openai.yaml
  • skills/pr-batch/SKILL.md
  • skills/pr-batch/agents/openai.yaml
  • skills/triage/agents/openai.yaml
  • skills/update-changelog/SKILL.md
  • skills/verify/agents/openai.yaml
  • workflows/adversarial-pr-review.md
  • workflows/pr-processing.md

Walkthrough

Adds a Codex native plugin manifest (.codex-plugin/plugin.json) with a Ruby validator, a Host Adapter Contract and ADR for Codex/Claude parity, a host-syntax symmetry lint, expanded OpenAI picker metadata across skills, and standardized *_SKILL_DIR helper path resolution wording, all wired into bin/validate with accompanying tests and documentation.

Changes

Dual-host adapter and plugin metadata follow-ups

Layer / File(s) Summary
Codex plugin manifest and validator
.codex-plugin/plugin.json, bin/codex-plugin-manifest-check, bin/codex-plugin-manifest-check-test.rb
Adds the plugin manifest and a validator checking metadata, skills path, interface fields, and consumer-policy content, with a Minitest suite.
Plugin manifest docs and install wiring
README.md, docs/installation-and-upgrades.md, bin/install-agent-workflows-test.bash
Documents the Codex native plugin path and asserts installer output excludes the plugin manifest.
OpenAI picker metadata expansion
bin/validate-openai-agent-metadata, bin/validate-openai-agent-metadata-test.rb, skills/*/agents/openai.yaml
Adds a validator for openai.yaml metadata files and populates picker display name/description/default prompt for multiple skills.
Host adapter contract and ADR
docs/host-adapter/contract.md, docs/adr/0001-identical-skill-text-across-hosts.md
Defines portable vs host-specific behavior, invocation syntax, approval models, path resolution, and availability checks, plus the byte-identical-text policy.
Host adapter syntax lint and markers
bin/validate-host-adapter-syntax, bin/host-adapter-syntax-test.rb, skills/address-review/SKILL.md, skills/autoreview/SKILL.md, workflows/pr-processing.md
Adds a lint enforcing marker pairing/availability-fallback rules and adds host-branch markers to skill/workflow docs.
Skill helper path resolution wording
skills/*/SKILL.md, workflows/*.md
Documents the env-var → loaded-skill-base → repo-local resolution chain for *_SKILL_DIR variables across skills and workflows.
bin/validate pipeline wiring
bin/validate
Adds the three new checks and their unit tests to the validation pipeline.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BinValidate as bin/validate
  participant PluginCheck as codex-plugin-manifest-check
  participant OpenAiCheck as validate-openai-agent-metadata
  participant HostLint as validate-host-adapter-syntax

  BinValidate->>PluginCheck: run against .codex-plugin/plugin.json
  PluginCheck-->>BinValidate: PASS/FAIL
  BinValidate->>OpenAiCheck: run against skills/*/agents/openai.yaml
  OpenAiCheck-->>BinValidate: PASS/FAIL
  BinValidate->>HostLint: run against skills/*/SKILL.md, workflows/*.md
  HostLint-->>BinValidate: PASS/FAIL
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main addition: host adapter support and Codex plugin metadata.
Linked Issues check ✅ Passed The PR covers #42, #58, #36, #60, and #43 with the contract, path-resolution updates, Codex manifest/metadata, and validation fixtures.
Out of Scope Changes check ✅ Passed The added docs, manifests, validators, and fixtures all support the stated contract, plugin, picker, and install-validation work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/awf-b3-host-adapter

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.

Comment thread bin/validate-host-adapter-syntax Outdated
"/goal"
].freeze

AVAILABLE_TOOL_TOKENS = [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AVAILABLE_TOOL_TOKENS only checks `codex review, codex review --, and /simplify, but docs/host-adapter/contract.md ("Availability Checks" section) explicitly lists /address-review and /code-review alongside /simplify as Claude Code slash commands that must be availability-checked before use. Because those two tokens aren't in this list, a future skill/workflow edit could hardcode /address-review or /code-review without a host-branch: available-tool marker or nearby fallback language, and bin/validate-host-adapter-syntax would pass it silently — undermining exactly the portability guarantee this PR introduces. Consider adding `/address-review` and `/code-review` (or the un-backticked forms actually used in prose) to this list.

CODEX_ONLY_END = "<!-- host-branch: codex-only end -->"
AVAILABLE_TOOL_START = "<!-- host-branch: available-tool start -->"
AVAILABLE_TOOL_END = "<!-- host-branch: available-tool end -->"
ALLOW_CODEX = "<!-- host-allow: codex-only -->"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ALLOW_CODEX (``) is wired into codex_only_lines but isn't exercised anywhere: it's not used in any current `skills//SKILL.md` or `workflows/.md` file, and `bin/host-adapter-syntax-test.rb` only tests the paired `codex-only start/end` markers, not this single-line marker. Minor, but it's an untested code path — either add a test fixture for it or drop it until it's needed.

Comment thread docs/host-adapter/contract.md Outdated
# Host Adapter Contract

Date: 2026-07-02
Status: proposed

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: this contract is marked Status: proposed, but ADR 0001 (docs/adr/0001-identical-skill-text-across-hosts.md), which this contract operationalizes, is Status: accepted — and bin/validate-host-adapter-syntax already enforces this contract's rules in CI via bin/validate. Worth bumping this to accepted (or clarifying why it's still proposed) so readers don't wonder whether the enforced rules are provisional.

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Reviewed this PR (host adapter contract + Codex plugin metadata). Overall this is solid: the Codex plugin manifest, its validator (bin/codex-plugin-manifest-check), the OpenAI picker metadata validator, and the host-adapter syntax linter are all well-tested and correctly wired into bin/validate. Specific checks I ran through:

  • bin/codex-plugin-manifest-check: symlink-escape guard in resolve_relative_path (realpath-based) is correct and covered by a dedicated test; manifest name/version/description/repository fields match VERSION/README.md as required.
  • Installer (bin/install-agent-workflows): confirmed .codex-plugin/plugin.json and the new validator scripts (codex-plugin-manifest-check, validate-host-adapter-syntax, validate-openai-agent-metadata) are correctly excluded from what gets copied/symlinked into installed Codex/Claude homes — matches the new negative assertions in bin/install-agent-workflows-test.bash.
  • Portability: grepped the updated skills/*/SKILL.md and workflows/*.md for stray /goal / codex review / worktree-pair mentions outside host-branch markers — didn't find any that the linter should be catching but isn't (aside from one gap noted inline).
  • Shell/Ruby helpers: no shell injection risk (Open3 calls all use argv arrays, not string interpolation into a shell); quoting in the new bash test assertions is consistent with the existing style.

Left 3 inline comments, all minor/nit level:

  1. bin/validate-host-adapter-syntaxAVAILABLE_TOOL_TOKENS doesn't include /address-review or /code-review, even though docs/host-adapter/contract.md explicitly calls both out as commands needing the same availability-check discipline as /simplify. Worth closing that gap so the linter actually enforces what the contract promises.
  2. bin/validate-host-adapter-syntax — the ALLOW_CODEX single-line marker is implemented but currently unused and untested.
  3. docs/host-adapter/contract.mdStatus: proposed vs. ADR 0001's Status: accepted, despite the contract already being enforced by CI.

No blocking correctness, security, or portability bugs found.

@justin808
justin808 marked this pull request as ready for review July 4, 2026 06:45

@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: bbb3fbf80c

ℹ️ 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 on lines +121 to +123
2. The loaded skill's own base directory, when the host exposes it for an
installed skill.
3. A repo-local pinned copy such as `.agents/skills/<name>`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Prefer pinned repo-local helpers before installed copies

In repos that pin .agents/skills/<name> for compatibility, this order makes an agent launched from a globally installed skill use the global helper before checking the pinned helper, even though the same contract says pinned repo-local copies may carry compatibility changes and should be resolved before the installed home. That can run stale or incompatible preflight helpers for a consumer checkout; put the repo-local pinned copy ahead of the loaded installed skill after explicit env overrides.

Useful? React with 👍 / 👎.

Comment thread bin/validate-host-adapter-syntax Outdated
].freeze

AVAILABLE_TOOL_PATTERNS = [
{ pattern: /`codex review|codex review --/, label: "codex review" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The alternation here isn't grouped, so it doesn't do what the other three patterns in this list do.

{ pattern: /`codex review|codex review --/, label: "codex review" },

This parses as two independent alternatives: `codex review (backtick immediately followed by the text) OR codex review -- (no backtick required). A plain-prose mention like Run codex review now (no surrounding backticks, no -- flag) matches neither branch, so it silently bypasses the "needs availability-check" gate this script exists to enforce.

Compare with the other three entries, which correctly use a non-capturing group so the prefix/suffix boundary conditions apply to the whole alternation:

{ pattern: %r{(?:`|^|\s)/address-review(?:\s|`|$)}, label: "/address-review" },

Likely fix: /`codex review(?:`| --)/ or similar, so any backtick-quoted or ---flagged mention is required to sit inside an available-tool branch or carry fallback language — matching the intent already demonstrated by the sibling patterns and by the test fixtures (which only ever exercise the backtick+no-flag case, so this gap isn't covered by bin/host-adapter-syntax-test.rb).

Comment thread bin/validate-host-adapter-syntax Outdated
next if allowed.include?(index)

window_start = [index - 3, 0].max
window_end = [index + 3, lines.length - 1].min

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The "needs availability-check or fallback language" heuristic just checks whether any word from AVAILABILITY_WORDS (e.g. available, fallback) appears anywhere in the ±3-line window around the flagged mention — it doesn't check that the word is actually talking about the flagged tool.

This produces a real false pass in this very PR's diff: skills/address-review/SKILL.md:874 reads

- If this skill conflicts with broader agent defaults, this file wins only for `/address-review` workflow behavior; ...
- Resolve the review thread after replying when the concern is actually addressed and a thread ID is **available**

The check treats line 875's "available" (about thread-ID availability, unrelated to whether the /address-review slash command exists on the host) as satisfying the fallback-language requirement for line 874's `/address-review` mention. It passes for the wrong reason.

Since this validator is the mechanism enforcing the new Host Adapter Contract's "availability-check host-specific tools before use" rule (docs/host-adapter/contract.md), a proximity-only keyword window gives false confidence — a future edit could remove real fallback language elsewhere in a paragraph and this check would still pass as long as an unrelated "available"/"fallback" word happens to sit within 3 lines. Worth tightening (e.g., require the availability word in the same sentence/line, or reference the specific tool label) or at least being aware this is a soft check, not a precise one.

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review summary

Reviewed the host adapter contract, Codex plugin manifest, OpenAI picker metadata, and the new host-syntax/manifest validation scripts, plus the path-resolution wording sweep across skills/ and workflows/.

Overall: this is solid, well-documented infra work. The ADR + contract doc give a clear rationale for keeping shared skill text byte-identical across hosts, the .codex-plugin/plugin.json manifest and its validator (bin/codex-plugin-manifest-check) correctly reject consumer-repo policy leakage and path escapes (including a symlink-escape test), and the path-resolution wording changes are applied consistently everywhere *_SKILL_DIR is used — I checked every occurrence across skills/ and workflows/ and didn't find a portability regression (no new hardcoded consumer commands, labels, branches, or paths were introduced).

I posted two inline findings on bin/validate-host-adapter-syntax, the new linter that's supposed to enforce "no host-specific tool mention without an availability-check/fallback":

  1. bin/validate-host-adapter-syntax:26 — the codex review pattern is missing a grouping around its alternation, so a plain-prose "codex review" (no backticks, no -- flag) matches neither branch and silently skips the check. The other three patterns in the same list use correct non-capturing groups; this one doesn't, and it isn't covered by the test fixtures either.
  2. bin/validate-host-adapter-syntax:145 — the "availability/fallback language nearby" check is a proximity-only keyword window (±3 lines) with no relevance check. It happens to produce a false pass in this PR's own diff (skills/address-review/SKILL.md:874), where an unrelated "available" on the next line (about thread-ID availability) satisfies the check for a /address-review mention that has no real fallback language of its own.

Neither finding blocks merge — the current doc content passes correctly either way — but both are real gaps in the new enforcement mechanism that could let a future edit slip past silently. Everything else (installer tests, symlink-mode coverage for agents/openai.yaml, bin/validate wiring, executable bits on new scripts) checked out.

Comment thread bin/validate-host-adapter-syntax Outdated
].freeze

AVAILABLE_TOOL_PATTERNS = [
{ pattern: /`codex review|codex review --/, label: "codex review" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The alternation here isn't grouped, so it doesn't do what the other three patterns in this list do.

{ pattern: /`codex review|codex review --/, label: "codex review" },

This parses as two independent alternatives: `codex review (backtick immediately followed by the text) OR codex review -- (no backtick required). A plain-prose mention like Run codex review now (no surrounding backticks, no -- flag) matches neither branch, so it silently bypasses the "needs availability-check" gate this script exists to enforce.

Compare with the other three entries, which correctly use a non-capturing group so the prefix/suffix boundary conditions apply to the whole alternation:

{ pattern: %r{(?:`|^|\s)/address-review(?:\s|`|$)}, label: "/address-review" },

Likely fix: /`codex review(?:`| --)/ or similar, so any backtick-quoted or ---flagged mention is required to sit inside an available-tool branch or carry fallback language — matching the intent already demonstrated by the sibling patterns and by the test fixtures (which only ever exercise the backtick+no-flag case, so this gap isn't covered by bin/host-adapter-syntax-test.rb).

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skills/update-changelog/SKILL.md (1)

112-117: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Wire UPDATE_CHANGELOG_SKILL_DIR through the host base first.

The current default still drops straight to .agents/skills/update-changelog, so an installed skill will ignore the host-exposed base directory and may fail to find bin/changelog-merged-prs. Please use the same env-var → loaded-skill-base → pinned-copy order here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/update-changelog/SKILL.md` around lines 112 - 117, The
UPDATE_CHANGELOG_SKILL_DIR fallback is skipping the host-exposed base directory
and going straight to the repo-local copy, which can break installed skills.
Update the lookup order in the update-changelog skill script to follow the same
env-var → loaded-skill-base → pinned-copy precedence used elsewhere, and ensure
the call to changelog-merged-prs resolves from that computed base rather than
assuming .agents/skills/update-changelog first.
🧹 Nitpick comments (3)
bin/codex-plugin-manifest-check (2)

12-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor: EXPECTED_SKILLS_PATH constant isn't reused for the literal path check.

validate_skills_path hardcodes "./skills/" instead of interpolating EXPECTED_SKILLS_PATH (declared at line 12), so the two need to stay manually in sync if the expected path ever changes.

Also applies to: 130-135

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bin/codex-plugin-manifest-check` at line 12, The skills path check in
validate_skills_path is hardcoding "./skills/" instead of reusing
EXPECTED_SKILLS_PATH, which can drift if the constant changes. Update
validate_skills_path to build the check from EXPECTED_SKILLS_PATH and apply the
same change anywhere else the literal path is repeated, so the constant is the
single source of truth.

114-128: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Only the first line of the README summary paragraph is compared.

body.each { ... return stripped unless stripped.empty? } returns as soon as it hits the first non-empty line after the title. If the README's summary paragraph wraps across multiple lines (common Markdown authoring style), the comparison in validate_manifest_metadata (line 100) will only ever see that first line, causing spurious "description must match README summary" failures for a semantically-unchanged, just-reformatted paragraph.

♻️ Proposed fix: join contiguous non-empty lines into one paragraph
   body.each do |line|
     stripped = line.strip
-    return stripped unless stripped.empty?
+    next if stripped.empty?
+    paragraph = [stripped]
+    body[(body.index(line) + 1)..].each do |next_line|
+      next_stripped = next_line.strip
+      break if next_stripped.empty?
+      paragraph << next_stripped
+    end
+    return paragraph.join(" ")
   end
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bin/codex-plugin-manifest-check` around lines 114 - 128,
`read_readme_description` only returns the first non-empty line after the README
title, so wrapped summary paragraphs are truncated before
`validate_manifest_metadata` compares them. Update `read_readme_description` to
collect and join the contiguous non-empty lines of the first paragraph after the
`# ` heading, then return that full paragraph string instead of a single line.
Keep the existing error handling for missing summary text.
bin/validate (1)

51-55: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Stale banner label: "seam doctor unit tests" now covers unrelated suites.

Three new, unrelated test files (codex-plugin-manifest-check-test.rb, validate-openai-agent-metadata-test.rb, host-adapter-syntax-test.rb) were appended under the == seam doctor unit tests == banner, making the label misleading for anyone scanning CI output.

✏️ Suggested rename
-echo "== seam doctor unit tests =="
+echo "== validator unit tests =="
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bin/validate` around lines 51 - 55, The `bin/validate` test section banner is
outdated because `== seam doctor unit tests ==` now precedes unrelated suites.
Update the echoed label to match the full group of tests run in this block, and
keep the banner aligned with the test commands such as
`bin/agent-workflow-seam-doctor-test.rb`,
`bin/codex-plugin-manifest-check-test.rb`,
`bin/validate-openai-agent-metadata-test.rb`, and
`bin/host-adapter-syntax-test.rb`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bin/codex-plugin-manifest-check`:
- Around line 20-34: The hardcoded branch-name matcher in
CONSUMER_POLICY_PATTERNS is inconsistent because the branch-name regex in
codex-plugin-manifest-check is case-sensitive while the sibling patterns are
not. Update the /\b(main|master)\b/ entry to use the same case-insensitive
behavior as the other policy patterns so references like Main or MASTER are
matched, and keep the change localized to the CONSUMER_POLICY_PATTERNS list.

In `@bin/validate-host-adapter-syntax`:
- Around line 138-149: The availability guard in validate-host-adapter-syntax is
too loose because the surrounding 3-line context in the main scan can let a
generic availability/fallback mention satisfy the check even when the tool
reference itself is unguarded. Tighten the logic in the lines.each_with_index
loop by requiring the availability/fallback words to appear in the same bullet
or paragraph as the matched tool pattern, using the existing
AVAILABLE_TOOL_PATTERNS and AVAILABILITY_WORDS symbols to locate and validate
the reference more precisely.

In `@bin/validate-openai-agent-metadata`:
- Around line 44-46: The validation in validate-openai-agent-metadata is too
broad because the current default_prompt scan pattern can mistakenly treat
dollar amounts like $20 as skill references. Tighten the matching logic in the
prompt_refs check so it only recognizes real skill IDs or directly compares
against the expected $token, and update the validation flow around
default_prompt and expected_skill accordingly. Add a regression test covering a
prompt that mentions money to ensure dollar values no longer fail validation.

In `@skills/plan-pr-batch/SKILL.md`:
- Around line 98-100: The PLAN_PR_BATCH_SKILL_DIR fallback is resolving too
early, which bypasses the host-exposed loaded-skill base and can miss
bin/pr-file-touch-map. Update the shell logic in the skill bootstrap to resolve
PLAN_PR_BATCH_SKILL_DIR by checking the explicit env var first, then the
loaded-skill base, then the repo-local pinned copy, and only then falling back
to .agents; keep the existing pr-file-touch-map invocation wired to that
resolved path.

---

Outside diff comments:
In `@skills/update-changelog/SKILL.md`:
- Around line 112-117: The UPDATE_CHANGELOG_SKILL_DIR fallback is skipping the
host-exposed base directory and going straight to the repo-local copy, which can
break installed skills. Update the lookup order in the update-changelog skill
script to follow the same env-var → loaded-skill-base → pinned-copy precedence
used elsewhere, and ensure the call to changelog-merged-prs resolves from that
computed base rather than assuming .agents/skills/update-changelog first.

---

Nitpick comments:
In `@bin/codex-plugin-manifest-check`:
- Line 12: The skills path check in validate_skills_path is hardcoding
"./skills/" instead of reusing EXPECTED_SKILLS_PATH, which can drift if the
constant changes. Update validate_skills_path to build the check from
EXPECTED_SKILLS_PATH and apply the same change anywhere else the literal path is
repeated, so the constant is the single source of truth.
- Around line 114-128: `read_readme_description` only returns the first
non-empty line after the README title, so wrapped summary paragraphs are
truncated before `validate_manifest_metadata` compares them. Update
`read_readme_description` to collect and join the contiguous non-empty lines of
the first paragraph after the `# ` heading, then return that full paragraph
string instead of a single line. Keep the existing error handling for missing
summary text.

In `@bin/validate`:
- Around line 51-55: The `bin/validate` test section banner is outdated because
`== seam doctor unit tests ==` now precedes unrelated suites. Update the echoed
label to match the full group of tests run in this block, and keep the banner
aligned with the test commands such as `bin/agent-workflow-seam-doctor-test.rb`,
`bin/codex-plugin-manifest-check-test.rb`,
`bin/validate-openai-agent-metadata-test.rb`, and
`bin/host-adapter-syntax-test.rb`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6dfacafd-f9d6-4ed9-a870-a948becae441

📥 Commits

Reviewing files that changed from the base of the PR and between 3cfc8fe and bbb3fbf.

📒 Files selected for processing (33)
  • .codex-plugin/plugin.json
  • README.md
  • bin/codex-plugin-manifest-check
  • bin/codex-plugin-manifest-check-test.rb
  • bin/host-adapter-syntax-test.rb
  • bin/install-agent-workflows-test.bash
  • bin/validate
  • bin/validate-host-adapter-syntax
  • bin/validate-openai-agent-metadata
  • bin/validate-openai-agent-metadata-test.rb
  • docs/adr/0001-identical-skill-text-across-hosts.md
  • docs/host-adapter/contract.md
  • docs/installation-and-upgrades.md
  • skills/address-review/SKILL.md
  • skills/address-review/agents/openai.yaml
  • skills/adversarial-pr-review/agents/openai.yaml
  • skills/autoreview/SKILL.md
  • skills/autoreview/agents/openai.yaml
  • skills/plan-pr-batch/SKILL.md
  • skills/post-merge-audit/SKILL.md
  • skills/post-merge-audit/agents/openai.yaml
  • skills/pr-batch/SKILL.md
  • skills/pr-batch/agents/openai.yaml
  • skills/replicate-ci/agents/openai.yaml
  • skills/spec/agents/openai.yaml
  • skills/triage/agents/openai.yaml
  • skills/update-changelog/SKILL.md
  • skills/update-changelog/agents/openai.yaml
  • skills/verify/agents/openai.yaml
  • workflows/address-review.md
  • workflows/adversarial-pr-review.md
  • workflows/continuous-evaluation-loop.md
  • workflows/pr-processing.md

Comment thread bin/codex-plugin-manifest-check
Comment thread bin/validate-host-adapter-syntax
Comment thread bin/validate-openai-agent-metadata Outdated
Comment thread skills/plan-pr-batch/SKILL.md Outdated
Comment on lines +98 to +100
`PLAN_PR_BATCH_SKILL_DIR="${PLAN_PR_BATCH_SKILL_DIR:-.agents/skills/plan-pr-batch}"; "${PLAN_PR_BATCH_SKILL_DIR}/bin/pr-file-touch-map" N --repo OWNER/REPO --cross-check`
Resolve `PLAN_PR_BATCH_SKILL_DIR` with the explicit env-var, loaded skill
base, repo-local pinned-copy chain before using the fallback assignment.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Resolve the helper dir before falling back to .agents.

This assignment still skips the host-exposed loaded-skill base and goes straight to the repo-local pinned copy, so installed/shared copies can miss bin/pr-file-touch-map. Please thread the env-var → loaded-skill-base → pinned-copy chain through the actual shell code.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/plan-pr-batch/SKILL.md` around lines 98 - 100, The
PLAN_PR_BATCH_SKILL_DIR fallback is resolving too early, which bypasses the
host-exposed loaded-skill base and can miss bin/pr-file-touch-map. Update the
shell logic in the skill bootstrap to resolve PLAN_PR_BATCH_SKILL_DIR by
checking the explicit env var first, then the loaded-skill base, then the
repo-local pinned copy, and only then falling back to .agents; keep the existing
pr-file-touch-map invocation wired to that resolved path.

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Summary

This is a well-structured PR that formalizes host-adapter conventions (Codex vs. Claude Code) with genuinely good self-validation: bin/codex-plugin-manifest-check, bin/validate-openai-agent-metadata, and bin/validate-host-adapter-syntax are all backed by unit tests and I traced their logic against the actual skills/*/SKILL.md and workflows/*.md content — the new checks correctly pass against the current tree, and I didn't find any portability violations (hardcoded consumer branches/labels/paths) in the new skills/*/agents/openai.yaml files or .codex-plugin/plugin.json.

Two things worth a look (posted as inline comments):

  1. Consistency gap in the "primary local/adversarial self-review gate" paragraph (skills/pr-batch/SKILL.md and workflows/pr-processing.md, both edited by this PR): the new "when that CLI is available" qualifier doesn't say what to do when it isn't available, unlike the canonical "Pre-Push AI Review And Simplify Gate" section and skills/autoreview/SKILL.md, which this same PR carefully teaches to fall back to Claude review or stop-and-report. Since this PR's whole point is making tool-availability handling explicit and non-silent, this looks like an oversight in these two duplicate restatements of the gate.
  2. Minor dead code in bin/codex-plugin-manifest-check: resolve_relative_path's path-traversal guard is unreachable given its only caller already hardcodes the manifest's skills value to "./skills/" before calling it. Not harmful, just worth trimming or noting why it's kept (e.g. defense-in-depth for a future looser caller).

Nice touches: the symlink-escape test/guard for the plugin manifest's skills path, the ADR explaining why install-time text rewriting was rejected, and the default_prompt cross-check tying each openai.yaml back to its own skill slug.

Comment thread skills/pr-batch/SKILL.md
`codex review --base origin/<base>` or the PR's real base, before PR creation or
update.
primary local/adversarial self-review gate, normally available `codex review --base origin/<base>` or the PR's real base, before PR creation or update.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This paragraph now says the primary review gate runs "when that CLI is available" but doesn't say what to do otherwise. Compare with skills/autoreview/SKILL.md (also touched by this PR), which explicitly chains: verify Codex is available → fall back to Claude review tooling → if neither exists, stop and report which engines are missing. The very next paragraph here (L263-264) already delegates the /simplify half of this same gate to the canonical "Pre-Push AI Review And Simplify Gate" section in pr-processing.md — this review-gate paragraph could do the same (or explicitly state the fallback) instead of silently leaving "not available" unhandled for a high-risk/hosted-CI-labeled PR.

Same gap exists in the near-duplicate paragraph in workflows/pr-processing.md around line 654.

end

expected = skill_names(File.join(root, EXPECTED_SKILLS_PATH))
actual = skill_names(skills_root)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

resolve_relative_path's traversal guard (path.absolute? || path.each_filename.any? { |part| part == ".." }) is unreachable in practice: its only caller, validate_skills_path, already returns early with "skills must be "./skills/"" unless manifest["skills"] == "./skills/" exactly — so raw_path is always that fixed relative literal by the time this method runs, and cleanpath on it never has an absolute path or a .. segment to catch. The symlink-escape check just below it (via File.realpath) is still reachable and is exercised by test_skills_path_must_not_escape_plugin_root_through_symlink, but this specific guard isn't covered by any test and can't be exercised given the current call site. Not harmful, just worth trimming or leaving a comment noting it's intentional defense-in-depth for a future looser caller.

@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: 4e64961505

ℹ️ 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 on lines +36 to +37
unless value.is_a?(String) && !value.strip.empty?
failures << "#{relative_path}: interface.#{field} must be a non-empty string"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Enforce the OpenAI short_description length

The validator only rejects empty strings, so bin/validate passes the new openai.yaml files even when interface.short_description is below the documented 25-character minimum for Codex picker metadata; this commit already adds too-short values such as skills/pr-batch/agents/openai.yaml (23 chars), plus adversarial-pr-review, post-merge-audit, triage, and verify. Please enforce the 25–64 char constraint here so invalid picker metadata cannot ship through the new validation gate.

Useful? React with 👍 / 👎.

Comment thread bin/validate-host-adapter-syntax Outdated

require "pathname"

ROOT = Pathname.new(ARGV[0] || ".").expand_path

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unlike the two sibling validators added in this PR (codex-plugin-manifest-check resolves its root via File.expand_path("..", __dir__), validate-openai-agent-metadata via File.join(__dir__, "..")), this script defaults ROOT to "." — the process's current working directory — when no argument is given.

bin/validate happens to cd to the repo root before calling this script with no args, so the gate itself is fine. But if anyone runs bin/validate-host-adapter-syntax directly from another directory (e.g. from inside skills/, or after cd-ing into an installed pack subdirectory), ROOT.glob("skills/*/SKILL.md") + ROOT.glob("workflows/*.md") silently returns zero files and the script still prints PASS host adapter syntax — a false pass with no files actually checked, rather than an error.

Consider defaulting to File.expand_path("..", __dir__) like the other two validators for CWD-independent, fail-safe behavior.

Comment on lines +25 to +30
AVAILABLE_TOOL_PATTERNS = [
{ pattern: /(?:`|^|\s)codex review(?:`|\s+--|\s|$)/, label: "codex review" },
{ pattern: %r{(?:`|^|\s)/address-review(?:\s|`|$)}, label: "/address-review" },
{ pattern: %r{(?:`|^|\s)/code-review(?:\s|`|$)}, label: "/code-review" },
{ pattern: %r{(?:`|^|\s)/simplify(?:\s|`|$)}, label: "/simplify" }
].freeze

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor completeness gap: these patterns only match when the tool phrase is immediately followed by a backtick, `\s+--`, whitespace, or end-of-line. A mention followed by other punctuation (comma, period, closing paren) slips through undetected — e.g. the pre-existing workflows/pr-processing.md lines "...Cursor Bugbot, Codex review, and any repo-specific reviewer bot" and "...Greptile, Codex review, or another AI reviewer..." aren't flagged even though they lack adjacent availability/fallback language, simply because "review" is followed by a comma rather than whitespace/backtick.

Not a blocker (those two lines predate this PR and describe a GitHub-bot listing rather than the CLI), but it does mean the new host-adapter-syntax gate gives incomplete coverage for prose that mentions these tools with trailing punctuation. Might be worth tightening the lookaheads (e.g. [\s,.)]|$) so bin/validate doesn't give false confidence here.

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Summary

Reviewed this PR (Host Adapter Contract, Codex plugin metadata, OpenAI picker metadata, host-syntax linting, manifest validation) against portability rules, shell/Ruby helper safety, correctness, and security.

Overall: solid, well-scoped work. The three new Ruby validators (codex-plugin-manifest-check, validate-openai-agent-metadata, validate-host-adapter-syntax) are each backed by focused unit tests, including a good symlink-escape test for the plugin manifest's skills path resolution. The <!-- host-branch: ... --> marker usage across skills/*/SKILL.md and workflows/*.md is consistently paired and matches the new linter's rules; I checked every /goal, codex review, /address-review, /code-review, and /simplify occurrence in the changed files against the new patterns and they're all correctly wrapped or accompanied by availability language. The *_SKILL_DIR path-resolution wording is applied consistently across all touched skills/workflows and matches the new Host Adapter Contract doc. No hardcoded consumer-repo commands, labels, branches, or paths found in the shared skills//workflows/ text introduced by this PR. .codex-plugin/plugin.json is correctly excluded from the installer (verified bin/install-agent-workflows doesn't reference it, and the new installer test asserts it's absent from installed targets).

Findings (posted inline):

  1. bin/validate-host-adapter-syntax:6 — defaults its scan root to "." (CWD) rather than resolving via __dir__ like its two sibling validators. bin/validate masks this by cd-ing to the repo root first, but running the script directly from any other directory silently yields a vacuous PASS host adapter syntax (zero files scanned) instead of an error.
  2. bin/validate-host-adapter-syntax:25-30 (minor) — the AVAILABLE_TOOL_PATTERNS regexes require the tool name to be followed by backtick/--/whitespace/EOL, so mentions followed by a comma or period (e.g. pre-existing "Codex review," list items in workflows/pr-processing.md) aren't flagged, giving incomplete enforcement coverage.

No security, correctness, or portability issues found beyond the above. Nice attention to detail on the ADR and Host Adapter Contract docs.

Comment on lines 94 to 100
**For parallel batch scheduling, always pass `--cross-check`** so the local
diff and the Files API must independently agree on the path set — a
fail-safe against a silent under-report scheduling two colliding items into
the same wave:
Resolve `PLAN_PR_BATCH_SKILL_DIR` with the explicit env-var, loaded skill
base, repo-local pinned-copy chain before using the fallback assignment.
Then run:
`PLAN_PR_BATCH_SKILL_DIR="${PLAN_PR_BATCH_SKILL_DIR:-.agents/skills/plan-pr-batch}"; "${PLAN_PR_BATCH_SKILL_DIR}/bin/pr-file-touch-map" N --repo OWNER/REPO --cross-check`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: broken sentence — a clause was deleted instead of appended.

The edit removed the line the same wave: (which completed "...a fail-safe against a silent under-report scheduling two colliding items into the same wave:") and replaced it with the new PLAN_PR_BATCH_SKILL_DIR resolution guidance, but didn't preserve the original clause. The merged text now reads:

...a fail-safe against a silent under-report scheduling two colliding items into Resolve PLAN_PR_BATCH_SKILL_DIR with the explicit env-var, loaded skill base, repo-local pinned-copy chain before using the fallback assignment. Then run: PLAN_PR_BATCH_SKILL_DIR=...

This is ungrammatical and drops the explanation of why --cross-check matters (colliding items scheduled into the same wave). Suggest restoring the dropped clause, e.g.:

Suggested change
**For parallel batch scheduling, always pass `--cross-check`** so the local
diff and the Files API must independently agree on the path set — a
fail-safe against a silent under-report scheduling two colliding items into
the same wave:
Resolve `PLAN_PR_BATCH_SKILL_DIR` with the explicit env-var, loaded skill
base, repo-local pinned-copy chain before using the fallback assignment.
Then run:
`PLAN_PR_BATCH_SKILL_DIR="${PLAN_PR_BATCH_SKILL_DIR:-.agents/skills/plan-pr-batch}"; "${PLAN_PR_BATCH_SKILL_DIR}/bin/pr-file-touch-map" N --repo OWNER/REPO --cross-check`
the same wave. Resolve `PLAN_PR_BATCH_SKILL_DIR` with the explicit env-var, loaded skill
base, repo-local pinned-copy chain before using the fallback assignment.
Then run:

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Summary

Reviewed the diff for portability (per AGENTS.md Editing Rules), shell/Ruby helper safety, and general correctness.

Overall: the change is well-scoped and internally consistent. The new bin/codex-plugin-manifest-check, bin/validate-host-adapter-syntax, and bin/validate-openai-agent-metadata helpers are careful — symlink-escape is defended against in the manifest checker (resolve_relative_path resolves realpaths and checks prefix), the host-adapter linter's marker-pair/availability-word logic is unit-tested for the tricky cases (unbalanced markers, unrelated nearby "available" words), and the OpenAI metadata validator correctly avoids false-positives on $ dollar amounts. I did not find any hardcoded consumer-repo commands/labels/branches leaking into skills/, workflows/, .codex-plugin/plugin.json, or the new docs — the CONSUMER_POLICY_PATTERNS check in codex-plugin-manifest-check is a nice belt-and-suspenders guard for that. The installer (bin/install-agent-workflows) correctly never touches .codex-plugin/, matching the new negative test assertions and the ADR's stated boundary between the native-plugin path and the host-installer path.

One real bug found — left as an inline comment on skills/plan-pr-batch/SKILL.md (lines 94–100): an edit deleted the clause "the same wave:" instead of appending the new PLAN_PR_BATCH_SKILL_DIR resolution text after it, leaving a broken/nonsensical sentence and dropping the explanation of what the --cross-check fail-safe protects against.

Minor observations (non-blocking):

  • The three new validator scripts use inconsistent CLI conventions — codex-plugin-manifest-check takes --root DIR (OptionParser), while validate-openai-agent-metadata and validate-host-adapter-syntax take a positional root path. Not a bug, just a minor consistency nit for anyone scripting against these.
  • skills/*/agents/openai.yaml metadata was added for 10 skills in this PR, but 6 existing skills (continue, qa-stress, run-ci, status, tdd, verify-pr-fix) still don't have it. Presumably intentional/incremental per the ADR ("optional metadata"), just flagging the gap in case full coverage was intended.
  • A couple of rewordings that dodge the new codex review host-adapter-syntax lint (e.g. "Codex review" → "Codex-generated review" in skills/adversarial-pr-review/SKILL.md and workflows/adversarial-pr-review.md) read a little awkwardly, though they're arguably clearer about referring to bot-authored reviews rather than the CLI command, so not requesting a change.

I was unable to execute bin/validate / the Ruby test suite directly in this sandbox (all ruby invocations were blocked at the tool-approval layer), so the above is from static reading of the diff and the resulting files, not a live test run. The PR description's own QA evidence states these commands were run successfully locally.

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review

Overall this is a careful, well-tested change — the new Ruby validators (codex-plugin-manifest-check, validate-openai-agent-metadata, validate-host-adapter-syntax) each ship solid unit tests covering edge cases (symlink escape for the manifest skills path, YAML/JSON parse failures, marker-pair balance, availability-language detection), and the SKILL.md/workflow edits consistently pair codex review / /goal / /address-review / /code-review / /simplify mentions with availability-check or fallback language (or wrap them in <!-- host-branch: codex-only --> markers), matching the new bin/validate-host-adapter-syntax lint rules. git worktree add and isolation: 'worktree' stay paired everywhere they appear. No shell-injection or unsafe eval patterns in the new bin/ scripts — they're pure Ruby file/JSON/YAML processing.

Two things worth addressing before/after merge:

  1. No CHANGELOG.md entry. AGENTS.md names CHANGELOG.md as the changelog, and this repo's own workflows/pr-processing.md Review Completion Gate (item 9) requires either a changelog entry for user-visible changes or an explicit note that /update-changelog must run before the next release. This PR adds a new Host Adapter Contract, an ADR, three new bin/ validators wired into bin/validate, a Codex native plugin manifest, and new install/README/docs surface — all user-visible — but [Unreleased] in CHANGELOG.md wasn't touched.

  2. Host-adapter-syntax enforcement is narrowly scoped. bin/validate-host-adapter-syntax's AVAILABLE_TOOL_PATTERNS/CODEX_ONLY_TOKENS only cover /goal, codex review, /address-review, /code-review, and /simplify. Plenty of other host-specific slash-invocations remain unmarked elsewhere in skills/*/SKILL.md and workflows/*.md — e.g. /update-changelog (skills/update-changelog/SKILL.md), /verify (skills/autoreview/SKILL.md, skills/verify/SKILL.md), /plan, /pr-batch, /adversarial-pr-review, /plan-pr-batch — which per the new docs/host-adapter/contract.md Invocation Syntax table are Claude-Code-only forms (Codex uses $name). These are pre-existing lines this PR doesn't touch, so it's not a regression, but it does mean the portability contract this PR introduces is only partially enforced by the new linter. Worth a tracked follow-up to either broaden the token list or accept these as intentionally out of scope.

Nit: skills/adversarial-pr-review/SKILL.md and workflows/adversarial-pr-review.md reword "Codex review" to "Codex-generated review" — this happens to dodge the new codex review literal-phrase lint pattern rather than adding the "when available" annotation used consistently everywhere else in the diff. Given the sentence is really describing an advisory GitHub bot/check rather than "run this CLI," the rewording is defensible, but it's inconsistent with how every other codex review mention in this PR was handled.

@justin808
justin808 merged commit a467189 into main Jul 4, 2026
3 checks passed
@justin808
justin808 deleted the codex/awf-b3-host-adapter branch July 4, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant