Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
63330d9
feat: lint OpenAI Codex plugins and marketplaces
github-actions[bot] Jul 25, 2026
3b99a22
Merge branch 'main' into codex-plugin-rules
stbenjam Jul 25, 2026
bd8d755
[Auto] Address review panel findings on Codex plugin rules
github-actions[bot] Jul 26, 2026
af5c056
[Auto] Merge branch 'main' into codex-plugin-rules
github-actions[bot] Jul 26, 2026
300824c
[Auto] Regenerate report card after merging main
github-actions[bot] Jul 26, 2026
aec70d2
Merge branch 'main' into codex-plugin-rules
stbenjam Jul 26, 2026
d1acefc
Merge remote-tracking branch 'origin/main' into codex-plugin-rules
github-actions[bot] Jul 26, 2026
253a9d9
[Auto] Address Codex review feedback on Codex plugin linting
github-actions[bot] Jul 26, 2026
857053e
Merge branch 'main' into codex-plugin-rules
stbenjam Jul 26, 2026
d783746
Address Codex review feedback: discovery gaps and shape checks
not-stbenjam Jul 26, 2026
7ac7f7f
Route Codex mcpServers, malformed inline hooks, and Codex-only docs
not-stbenjam Jul 26, 2026
9c56371
Merge branch 'main' into codex-plugin-rules
stbenjam Jul 26, 2026
87f1bb0
Stand down on installed plugins; fix discovery and docs gaps
not-stbenjam Jul 26, 2026
d355f76
Merge remote-tracking branch 'origin/codex-plugin-rules' into codex-p…
not-stbenjam Jul 26, 2026
076d3ce
Give inline config blocks identity semantics
not-stbenjam Jul 26, 2026
9c8d0bf
Merge remote-tracking branch 'origin/main' into codex-plugin-rules
not-stbenjam Jul 26, 2026
3564027
Harden path resolution, discovery containment and docs authorship
not-stbenjam Jul 26, 2026
3ec06b3
Only report cross-catalog duplicates when the sources differ
not-stbenjam Jul 26, 2026
1a4cc0e
Close the .codex-plugin symlink escape and the panel's follow-ups
not-stbenjam Jul 26, 2026
e954170
Remove review archaeology from comments, tests and docs
not-stbenjam Jul 26, 2026
0ad0067
Merge remote-tracking branch 'origin/main' into codex-plugin-rules
not-stbenjam Jul 26, 2026
94262e3
Contain symlinked discovery paths and harden the generated docs
not-stbenjam Jul 26, 2026
291b609
Close the remaining containment and allocation edge cases
not-stbenjam Jul 26, 2026
ad0107b
Scope containment per plugin and fix the remaining docs gaps
not-stbenjam Jul 26, 2026
427ce62
Contain skill references, fix generated-HTML escaping, widen hook cov…
not-stbenjam Jul 26, 2026
373420e
Restrict generated link schemes and fix nested-plugin attribution
not-stbenjam Jul 26, 2026
416ac84
Address review round ten
not-stbenjam Jul 26, 2026
bd6bb33
Address panel verdict and review round eleven
not-stbenjam Jul 26, 2026
bc3d99f
Merge remote-tracking branch 'origin/main' into codex-plugin-rules
not-stbenjam Jul 26, 2026
18cd052
Regenerate card after merge
not-stbenjam Jul 26, 2026
ce17fce
Address panel verdict: parse-depth crash, tense, spec corrections
not-stbenjam Jul 26, 2026
4227a95
Fix parse-depth tests and four Codex review findings
not-stbenjam Jul 26, 2026
ccced41
Contain the --type seeds, harden docs input, correct the spec premise
not-stbenjam Jul 26, 2026
42016d5
Harden Codex format linting and OpenAI metadata
not-stbenjam Jul 27, 2026
ec9012f
Preserve Agent Skill structure fingerprints
not-stbenjam Jul 27, 2026
21f52cb
Group Codex plugins in the lint tree
not-stbenjam Jul 27, 2026
8026391
Address review round twelve: primary type, docs hardening, shared con…
not-stbenjam Jul 27, 2026
a33dbc2
Fix real-catalog false positives found linting openai/plugins
not-stbenjam Jul 27, 2026
679f42f
Address Codex review round thirteen
not-stbenjam Jul 27, 2026
56f8c1b
Trim review-round accretion from the test suite
not-stbenjam Jul 27, 2026
a9f168d
Address Codex round fourteen: two crash guards and meta-field folding
not-stbenjam Jul 27, 2026
28172ee
Restore Codex plugin prose to the lint tree and close panel-verified …
not-stbenjam Jul 27, 2026
dd19a08
Close the second panel's findings and the round-fifteen gaps
not-stbenjam Jul 27, 2026
74ec317
Make ecosystem provenance a first-class primitive
not-stbenjam Jul 27, 2026
c25cbbc
Close the review gaps the single-pass architecture exposed
not-stbenjam Jul 27, 2026
c924978
Fix the redaction ReDoS and the fourth panel's remaining items
not-stbenjam Jul 27, 2026
7a14d98
Give the redaction-linearity guard headroom for traced coverage
not-stbenjam Jul 27, 2026
3cdee89
Fix the fifth panel's blockers: dead HTML page, quadratic redaction, …
not-stbenjam Jul 27, 2026
6a1d5c7
Remove accidentally committed worktree gitlink, ignore .worktrees/
not-stbenjam Jul 27, 2026
b8f7751
Extract script blocks by splitting, not a tag regex
not-stbenjam Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .agents/skills/skillsaw-maintenance/SKILL.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

136 changes: 136 additions & 0 deletions .agents/skills/skillsaw-maintenance/references/codex.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions .apm/instructions/development.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ from the markdown-it-py AST — read it via `block.markdown` (a
hooks, MCP JSON) subclass `JsonConfigBlock` instead; dedicated rules find
them with `find(SettingsBlock)`. Never add a config file type under
`ContentBlock` — content rules would then lint its JSON as instruction text.
- **Structured YAML config gets a direct `LintTarget` subclass, never
`ContentBlock`** — `OpenAIMetadataBlock` is the pattern. It is deliberately
neither `ContentBlock` (content rules would lint its YAML as instruction
text) nor `JsonConfigBlock` (that hierarchy is JSON-specific and file-level;
YAML keeps line numbers via `read_yaml_commented()`).

Never require line numbers for JSON files — the `json` module does not
preserve them. Keep JSON rules at file-level reporting.
Expand All @@ -129,3 +134,41 @@ preserve them. Keep JSON rules at file-level reporting.
duplicate key on every run and never converges (issue #321).
- **Add new SAFE-autofix edge cases** to the `tests/fixtures/autofix/safe-idempotency`
fixture so `TestSafeAutofixIdempotency` guards them; update `EXPECTED_SAFE_VIOLATIONS` when the fixture grows.
- **Autofix stands down entirely for plugins installed under `.codex/plugins/`**
— vendor-managed content is diagnostic-only, so every rule's `fix()` silently
no-ops there, by design. A new rule's fix needs no guard of its own for that
case, and a "fix didn't apply" report from such a path is expected behavior,
not a bug.

## Ecosystem provenance

"Which ecosystem owns this plugin directory" is decided in exactly one
place: `RepositoryContext.provenance()`, which returns a cached
`PluginProvenance` record per directory. Never answer an ownership
question with a fresh filesystem probe in a rule or in the tree builder —
two call sites probing independently is how a directory falls between
per-ecosystem attach paths and loses its content silently.

- **Evidence is filesystem-first and `--type`-invariant.** An override
changes what discovery walks, not what the author declared, so
provenance reads markers, contained manifests, and catalog files
directly (`_codex_catalog_files()`), never discovery output.
- **The lint tree builds plugins in ONE pass** over the union of claimed
directories. Each directory gets one container; prose (`commands/`,
`agents/`, `rules/`, README) attaches once with containment; config
files attach per claiming ecosystem through the contained helpers.
Never add a second per-ecosystem plugin loop.
- **Format rules gate on provenance, not on tool names in-line.**
Claude-format rules skip `context.is_codex_only_plugin(...)`
directories; ecosystem-tightened checks (hooks/MCP shapes) apply only
to that ecosystem's exclusive directories, so dual-manifest plugins
keep their established results.

**Adding an ecosystem** (the next Codex): add its evidence probe to
`RepositoryContext.provenance()` and its catalog enumeration beside
`_codex_catalog_files()`; add its config-file cluster to the single
plugin pass in `build_lint_tree` (attached through a contained helper);
gate its format rules on its provenance and keep them out of
`is_codex_only_plugin`-exempt directories; extend the union in
`merge_plugin_dirs` callers if it discovers plugin directories of its
own. Prose needs no work — every claimed directory already gets it.
13 changes: 10 additions & 3 deletions .apm/skills/skillsaw-maintenance/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: skillsaw-maintenance
description: Analyze upstream specs (agentskills.io, Claude Code plugin/marketplace format, OpenClaw, MCP, CodeRabbit, APM) for changes, identify gaps in skillsaw's rule coverage, and create or update PRs to close those gaps. Use when performing periodic maintenance on the skillsaw linter.
description: Analyze upstream specs (agentskills.io, Claude Code plugin/marketplace format, OpenAI Codex plugins/marketplace, OpenClaw, MCP, CodeRabbit, APM) for changes, identify gaps in skillsaw's rule coverage, and create or update PRs to close those gaps. Use when performing periodic maintenance on the skillsaw linter.
compatibility: Requires git, gh CLI, and internet access
license: Apache-2.0
user-invocable: true
Expand Down Expand Up @@ -35,15 +35,22 @@ to check, the rules that map, and sync notes (hand-copied values that can drift)
|---|---|---|
| Agent Skills (agentskills.io) | [references/agentskills.md](references/agentskills.md) | `agentskills/` |
| Claude Code (plugins, marketplace, .claude, hooks, mcp, skills, agents) | [references/claude.md](references/claude.md) | `plugins/`, `commands/`, `marketplace/`, `hooks/`, `mcp/`, `skills/`, `agents/` |
| OpenAI Codex (plugins, marketplaces, `agents/openai.yaml` skill metadata) | [references/codex.md](references/codex.md) | `codex/` |
| OpenClaw | [references/openclaw.md](references/openclaw.md) | `openclaw/` |
| Model Context Protocol | [references/mcp.md](references/mcp.md) | `mcp/` |
| CodeRabbit (`.coderabbit.yaml`) | [references/coderabbit.md](references/coderabbit.md) | `coderabbit/` |
| APM (`.apm/`) | [references/apm.md](references/apm.md) | `apm/` |

Pay special attention to the **Sync notes** in each reference: rules that hand-copy
upstream value sets (OpenClaw's install kinds/os/archive, MCP transport types, APM
required fields) are the highest drift risk. OpenClaw is the top risk — it publishes no
JSON Schema, so skillsaw's rule is the de-facto validator.
required fields, Codex's policy enums) are the highest drift risk. OpenClaw is the top
risk — it publishes no JSON Schema, so skillsaw's rule is the de-facto validator. Codex
is second: its prose spec publishes no schema, while a separate field-level spec inside
the `plugin-creator` skill is stricter — so the two can drift apart from each other.

Where a reference marks a check as deliberately omitted, that omission is binding. A
"missing" check listed there was left out on purpose; add it only when the upstream
spec changes.

## Step 2: Identify gaps

Expand Down
Loading