feat: Codex-compatible skills distribution (spike) - #88
Conversation
Phase 2 of the Codex port spike. Extends scripts/build-codex.mjs and the dist/codex distribution so PR #88 can come out of draft. - Determinism: the build now builds twice and asserts byte-identical generated output (.agents/ + agents/openai.yaml). - Drift guard: new --check flag rebuilds into a temp dir and diffs against the committed dist/codex, exiting nonzero on any drift. - Codex 1024-char description cap: confirmed against codex-cli 0.118.0 that 3 skills (creative-direction, integration-orchestrator, logo-design) failed to load because their descriptions exceeded 1024 chars. The build now emits a description truncated at a sentence boundary and preserves the full original in the sidecar (description_full). A gating check (E) prevents regression. Re-running the real CLI confirms all 102 skills now load with zero parse errors. - Description-discrimination audit (heuristic): writes dist/codex/SKILL_DISCOVERY_AUDIT.md with a fixture table, low-confidence prompts, and flagged descriptions. Labeled heuristic throughout. - openai.yaml sanity: asserts the file exists, every detected MCP server has a commented entry, and no uncommented urls/keys/tokens are present. - PORT_NOTES.md updated with steps 1-4 results and an owner smoke-test recipe (notes Codex also reads ~/.codex/skills/). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 2: verification + hardening (automated results)New commit Gating checks: all PASS
Real Codex CLI discovery (best effort, done)Verified against installed codex-cli 0.118.0 (logged in). Loaded the emitted
Discovery audit (heuristic)
One remaining gate before mergeThe authoritative check is the owner's live smoke test (recipe in |
Add scripts/build-codex.mjs, a dependency-free Node ESM build step that produces a Codex distribution of the 102-skill catalog under dist/codex/. - Walks skills/<name>/ and copies each into dist/codex/.agents/skills/<name>/, preserving the references/ subtree byte for byte (488 files). - Normalizes SKILL.md frontmatter to the portable core (name + description); moves category, catalog_summary, display_order into a per-skill sidecar (references/_claude-frontmatter-extras.yaml) so the port is reversible. - Leaves SKILL.md bodies untouched. - Detects MCP references and emits dist/codex/agents/openai.yaml as a commented wiring template (Ahrefs MCP powers the SEO audit suite; no real config is fabricated). - Includes a validation pass (PASS/FAIL per check): non-empty name/description, skill-count parity, reference-file coverage, clean frontmatter. Adds dist/codex/PORT_NOTES.md and dist/codex/README.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 2 of the Codex port spike. Extends scripts/build-codex.mjs and the dist/codex distribution so PR #88 can come out of draft. - Determinism: the build now builds twice and asserts byte-identical generated output (.agents/ + agents/openai.yaml). - Drift guard: new --check flag rebuilds into a temp dir and diffs against the committed dist/codex, exiting nonzero on any drift. - Codex 1024-char description cap: confirmed against codex-cli 0.118.0 that 3 skills (creative-direction, integration-orchestrator, logo-design) failed to load because their descriptions exceeded 1024 chars. The build now emits a description truncated at a sentence boundary and preserves the full original in the sidecar (description_full). A gating check (E) prevents regression. Re-running the real CLI confirms all 102 skills now load with zero parse errors. - Description-discrimination audit (heuristic): writes dist/codex/SKILL_DISCOVERY_AUDIT.md with a fixture table, low-confidence prompts, and flagged descriptions. Labeled heuristic throughout. - openai.yaml sanity: asserts the file exists, every detected MCP server has a commented entry, and no uncommented urls/keys/tokens are present. - PORT_NOTES.md updated with steps 1-4 results and an owner smoke-test recipe (notes Codex also reads ~/.codex/skills/). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s legal) Rebased feat/port-codex onto main after PR #90 shortened the three over-cap source descriptions. Rebuilt the distribution from the corrected catalog: - creative-direction (900), integration-orchestrator (968), logo-design (976) are now under the 1024-char cap, so the truncation logic stays dormant: their emitted SKILL.md descriptions are the full source text and the description_full sidecar entries are gone. - Skill count 102; --check PASS (committed dist matches a fresh rebuild); zero emitted descriptions exceed 1024 chars. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
) scripts/build-pi.mjs --check byte-compares the committed distribution against a fresh build. The guard worked, but nothing invoked it, so it had never run in CI once. That is how dist/pi shipped 102 of 103 skills for a full release cycle without a red build, which #104 had to clean up. Triggers on skills/**, dist/**, the builder, .gitattributes, and this file. .gitattributes is load-bearing rather than incidental: the guard compares bytes, so the committed line-ending policy is what keeps a Windows checkout from reading as wholly different. Deliberate consequence, documented in the workflow header and the PR body: a skills-only PR that does not rebuild dist/pi goes red. That is the invariant working, not noise. A shipped distribution has to move with its source in the same PR or the catalog on disk and the catalog users install drift apart silently. The fix for a red run is to rebuild and commit, never to relax the path filter. Scoped to dist/pi, the only distribution target on main. A marked TODO(dist-targets) covers extending to the Codex and Antigravity builders when #87 and #88 land; pre-wiring a step for a builder that does not exist yet would fail on a missing file and teach people to ignore this workflow. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
STATUS (2026-08-05): Held deliberately, not merge-ready, not abandoned. This draft predates the .gitattributes/LF policy (#104), the dist drift guard (#107), and subsequent skills changes, so its tree is stale against source and its line endings predate the current rules. Reviving it means: rebase onto current main, FULL rebuild from current source via its builder, renormalize, 103-count parity vs SKILLS.lock, guard proven red/green for this target, and dist-drift.yml extended per its TODO(dist-targets). Parked pending demand evidence for this platform; do not merge as-is. |
Summary
Spike: a repeatable, dependency-free build step that produces a Codex-compatible distribution of the skills catalog under
dist/codex/, plus a feasibility writeup. Lane was limited toscripts/build-codex.mjsanddist/codex/**; nothing else was touched.Skill count
skills/<name>/SKILL.md); 102 emitted todist/codex/.agents/skills/.Validation results
Run
node scripts/build-codex.mjs-- all checks PASS:[PASS] A.every emitted SKILL.md has non-empty name + description (102 ok)[PASS] B.emitted skill count equals source (source=102 emitted=102)[PASS] C.every source references file has an emitted counterpart[PASS] D.no emitted frontmatter has keys beyond name/descriptionFrontmatter normalization
Every source skill carries 5 uniform keys. The build keeps the portable core (
name,description) on each emitted SKILL.md and moves the rest --category,catalog_summary,display_order-- into a per-skill sidecarreferences/_claude-frontmatter-extras.yaml. Fully reversible; SKILL.md bodies are left byte-identical.MCP template note
dist/codex/agents/openai.yamlis a commented template listing detected MCP servers with placeholderurl/name/transportfields for the operator to fill in. No real server config is fabricated. Detected: Ahrefs MCP (7 skills, the SEO audit suite), Similarweb, plus Chrome/Playwright/Windows/Linear/GitHub (integration-orchestrator examples), and 7 generic MCP mentions flagged for operator review.Feasibility
Mechanically straightforward and low risk: a reversible, dependency-free transform yields a clean
.agents/skills/tree for all 102 skills, with the only real integration work being operator-supplied MCP server config.See
dist/codex/PORT_NOTES.mdfor the full writeup.🤖 Generated with Claude Code