← Files AkinatorARCHIVED FILE

rules/07-codex-pack-is-generated.md

6.49 KB · Oct 3, 2026 · 06:33 UTC

↓ Download file

# Rule 07 - The Codex pack is generated, never hand-edited

## Purpose

Akinator ships the same behavioral contract to two platforms. If both copies are
maintained by hand they will diverge, and the divergence will be invisible: the
Claude user and the Codex user will each believe they are running the same
plugin while getting different instructions.

That is the exact failure Akinator exists to prevent - a forked truth with no
mechanism to detect the fork. Shipping it inside the plugin would be
disqualifying.

The canonical skill is `skills/everything/`. The portable pack is a build output.

## Applies to

- **In scope:** everything under `.agents/`, generated from `skills/everything/`
  by `scripts/build_codex_pack.py`: the one skill projected as `akinator`
  (`.agents/skills/akinator/`, with its references and its tools), the
  **portable contract** `.agents/AGENTS.md`, and the Cursor rule
  `.agents/cursor/akinator.mdc` (the contract as an always-applied Cursor rule).
  Codex and Cursor both read skills from the same folder, so one pack serves
  both. The installers copy all of it into other places, so it names no file
  that only this checkout has. See
  `rules/12-artifacts-that-travel-name-nothing-local.md`.
- **Out of scope:** `skills/**` (canonical, hand-written),
  `.codex-plugin/plugin.json` (a hand-maintained manifest, not derived from the
  skills), and target repositories' own files. Also out of scope, and easy to
  confuse with `.agents/AGENTS.md`: the **root** `AGENTS.md`. It is Akinator's
  own router, one of eleven rendered from `context/router-contract.md` by
  `scripts/render_routers.py` - see `rules/09-routers-are-rendered-from-one-contract.md`.
  It does not travel, so it names its generator by path like any router, and it
  is a different generator from this rule's. Two generators writing one file
  would be a fork with extra steps, which is why they never overlap.

## Mandatory rules

1. Everything under `.agents/` is written only by `scripts/build_codex_pack.py`.
2. Every generated file carries a banner saying it is generated and how to get
   a correct copy. **How it says so depends on whether the file travels.** A
   generated file that stays in this repository names its generator by path,
   because the reader can run it. A generated file that is installed into other
   repositories names no file at all - it names its origin and its refresh path
   instead, because a generator path is false wherever it lands. Everything in
   this rule's scope travels, so all of it takes the second form. See
   `rules/12-artifacts-that-travel-name-nothing-local.md`, which governs the
   content of these banners; this rule governs who writes them.
3. Generation is **deterministic**: the same `skills/everything/` tree produces
   byte-identical output. No timestamps, no absolute paths, no unordered
   iteration.
4. A change to the canonical skill, its references or its tools regenerates the pack in the **same batch**.
5. CI runs the drift check. A drifted pack fails the build.

## Prohibited patterns

```bash
# WRONG - editing the build output
vim .agents/skills/akinator/SKILL.md
```

The next regeneration silently deletes the edit, and until then the two
platforms disagree.

```python
# WRONG - non-deterministic generation
header = f"Generated {datetime.now()} from {os.path.abspath(src)}"
```

Every run produces a diff, so the drift check becomes noise and gets disabled -
after which real drift returns undetected.

```python
# WRONG - unordered iteration
for path in src_dir.iterdir():      # filesystem order varies by platform
```

## Correct pattern

```bash
# RIGHT - edit the canonical skill, then regenerate in the same batch
vim skills/everything/references/akinator.md
python scripts/build_codex_pack.py --write
```

```python
# RIGHT - deterministic: sorted, relative, no clock. And the banner names no
# file, because this output is installed into repositories that have none of
# them - see rules/12.
for path in sorted(src_dir.rglob("SKILL.md")):
    banner = (f"Installed from the Akinator plugin - the canonical "
              f"{path.parent.name} skill. To update: reinstall Akinator.")
```

```python
# WRONG - true here, false everywhere this file is installed. This exact line
# shipped, and produced 21 of the 22 HIGH findings a target repository got -
# one per skill; the portable contract's own banner produced the other.
banner = f"Generated by scripts/build_codex_pack.py from {rel(path)}."
```

## Enforcement

- Mechanism: `scripts/build_codex_pack.py` - `--check` regenerates in memory and
  diffs against the tree, exiting non-zero on any difference. This detects both
  a hand-edit and a stale pack, because both produce the same symptom.
- Mechanism: `tests/test_codex_pack.py::test_pack_is_not_drifted` runs the drift
  check with the suite, and
  `tests/test_codex_pack.py::test_generation_is_deterministic` generates twice
  and asserts byte-identical output.
- Mechanism: `.github/workflows/ci.yml` runs the drift check on every push.
- Type: script check in CI, plus two unit tests.
- How it fails: the drift check prints each differing path and whether it is
  missing, extra or changed.
- Last observed passing: 2026-09-18

**Never a git hook** - see `rules/05-no-git-hook-complication.md`.

## Exceptions

None for anything under `.agents/`.

If the Codex pack needs content the Claude skills do not have, that content goes
into the **generator** as a documented transformation - not into the output. The
generator is the place where per-platform differences are expressed, because a
transformation is reviewable and reproducible while a hand-edit is neither.

## Related

- Rules: `rules/12-artifacts-that-travel-name-nothing-local.md` - what a
  generated file that leaves this repository may say. This rule owns *who
  writes* the pack; that one owns *what it may claim*.
- Skills: `akinator-contextify` - generated-beats-written, and the conventions
  for generated artifacts
- Docs: `docs/compatibility.md` - the platform contracts this relies on
- ADR: `docs/adr/0002-codex-pack-generated-from-claude-skills.md`
- ADR: `docs/adr/0007-vendored-artifacts-declare-origin-not-generator.md`
- ADR: `docs/adr/0009-one-skill-one-command-one-installer.md`

## Definition of done

- [x] The constraint is stated as a testable proposition.
- [x] Enforcement mechanisms exist in the tree and are named by path.
- [x] The mechanisms are not git hooks.
- [x] Prohibited and correct patterns are shown.
- [x] The absence of an exception path is deliberate, with the alternative named.
- [x] The rule is indexed and reflected in every router.

SHA-256: 98e3cf37b720cc66003eed72244cee1b6b4c22cb0cb37c05c7231a9829ca0292