skill-creator: init_skill.py leaves a partial scaffold when --interface validation fails
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
Deterministically invalid --interface input is rejected only after init_skill.py creates a skill directory and SKILL.md. The failed invocation leaves a partial scaffold, so correcting the argument and retrying at the same path fails because the directory already exists.
Related: #44187 covers validation-before-side-effects issues in bundled helpers and empty required metadata; this report specifically concerns initializer mutation ordering and retryability after invalid --interface input.
Affected source
Inspected current main commit: 31ffe2bc9adccfe5fd3d29208250f796a13aa7a0 (2026-09-15).
- codex-rs/skills/src/assets/samples/skill-creator/scripts/init_skill.py
- codex-rs/skills/src/assets/samples/skill-creator/scripts/generate_openai_yaml.py
Reproduction
Run from a checkout of the commit above with Python 3. All generated files are synthetic and confined to a new temporary directory.
bash <<'SH'
scripts=codex-rs/skills/src/assets/samples/skill-creator/scripts
repro_root="$(mktemp -d)"
python3 -B "$scripts/init_skill.py" repro-skill --path "$repro_root" \
--interface unsupported_field=value
printf 'invalid_exit=%s\n' "$?"
ls -R "$repro_root"
python3 -B "$scripts/init_skill.py" repro-skill --path "$repro_root" \
--interface 'short_description=Create a small synthetic test skill'
printf 'corrected_retry_exit=%s\n' "$?"
SH
Observed: invalid_exit=1; the listing contains repro-skill/SKILL.md but no agents/openai.yaml. The corrected invocation reports Skill directory already exists and corrected_retry_exit=1.
Actual behavior
- Deterministically invalid interface input causes filesystem mutation before rejection.
- The skill directory and partial
SKILL.mdremain. agents/openai.yamlis not created.- A corrected retry fails on the existing-directory check.
Expected behavior
Reject invalid interface input before filesystem mutation. After failure, the skill directory, SKILL.md, and agents/openai.yaml should all be absent. A corrected valid command should then succeed at the same path.
Root cause
For a new target, the current call order is:
init_skill()
-> skill_dir.mkdir()
-> SKILL.md write
-> write_openai_yaml()
-> parse_interface_overrides()
The interface parser rejects unsupported keys, missing =, and empty keys after the first two filesystem writes have already occurred. Returning failure does not remove those artifacts, and the next invocation encounters the existing-directory check.
Potential approach
Move interface parsing and validation of the generated interface into a preflight step with no filesystem writes, and run it before directory creation. Reuse the same interface-building logic from write_openai_yaml(), including the existing parser and allowed-key list.
Extracting build_interface_lines() is one possible minimal approach, tested in an isolated candidate. It preserves validation of both explicit and generated descriptions without duplicating allowed keys. This suggestion addresses deterministic input failures; it does not propose a general filesystem transaction system.
Focused validation
The isolated candidate passed:
- Invalid interface input: nonzero exit and zero scaffold artifacts.
- Corrected retry at the same path: PASS.
- Valid interface generation: PASS.
- Existing-directory protection, including unchanged file contents: PASS.
- Normal resources and example generation: PASS.
- Existing description-length boundaries, generated-value validation, empty-value fallback, and duplicate-override behavior: PASS.
The focused suite passed 25/25 tests: 10 validator cases and 15 initializer/generator cases. The latter include six invalid-input cases with artifact and retry assertions. An independent rerun produced the same result.
These are local synthetic-fixture results, not upstream CI results. The unmodified helper files used for reproduction match the inspected upstream source byte-for-byte. Production and vendor bundles were left unchanged.
Environment
- OS: macOS 15.7.4, arm64.
- Standalone Codex CLI:
0.153.4. - Desktop app:
26.908.40834; bundled Codex:0.154.0-alpha.6.2. - Inspected main:
31ffe2bc9adccfe5fd3d29208250f796a13aa7a0. - Stable source comparison:
rust-v0.154.0(6b9826e3aa83b1a5947db50f4332cb9c65f1b340); the helper files are identical.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/skills/src/assets/samples/skill-creator/scripts/init_skill.py and generate_openai_yaml.py, then run the documented temporary-directory reproduction. Trace interface parsing and generated interface validation relative to directory and SKILL.md creation. Done means invalid input leaves no scaffold, a corrected retry succeeds at the same path, and valid generation plus existing-directory protection remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100