Repository navigation
v7.1.0
What's changed in v7.1.0
Highlights
One instruction file for Claude Code and Codex. .claude/CLAUDE.md and .codex/AGENTS.md are
now links to the project's root AGENTS.md, so both harnesses load the same rules. Where the system
refuses links, each is a one-line pointer instead, and init and upgrade say which form they
wrote. If you edited .claude/CLAUDE.md, upgrade backs your copy up and replaces it: move what
you still need into AGENTS.md (see
UPGRADING.md).
Codex starts Specnaut's agents by name. .codex/config.toml now enables agents, and AGENTS.md
names the agent for each delegated step of the chain. .codex/goal.md, which Codex never read, is
retired.
Specnaut no longer writes or reads outside the project through a planted link. The containment
check now follows a link's text the way the operating system does, segment by segment. It refuses a
link that passes through a directory that does not exist yet. Before, a link chain in a cloned
repository could make init, upgrade or diff touch a file outside the project.
/ship tag refuses a dirty working tree and lists what is uncommitted, instead of tagging a
HEAD that does not match the files beside it.
Features
- Link .codex/AGENTS.md, retire goal.md, and make Codex delegate by name
- Link .claude/CLAUDE.md to the root AGENTS.md
- Carry the backlog pointer, the integrations and the agent per step in AGENTS.md
- Plan a context link from what is on disk, and say what was written
- Write a context link, or its fallback, and read one without following it
- Model a context link and classify what is on disk at one
Bug fixes
- A reader reports a link through a missing directory as absent
- Fail closed on a dangling ancestor; report an unwalkable link in readEntry
- Refuse a link whose text passes through a missing directory
- Walk a link's text segment by segment, as the kernel does
- Skip context-link entries in the Go manifest; read
--!>marker closes - Report a staging cleanup failure instead of swallowing it
- Confirm the scripts that publish, and refuse a dirty tree in tag.sh
Adoption guide
These prompts help your AI agent adopt the new features in an existing project. Copy them into your harness, or run @specnaut-guide review-upgrade to be walked through automatically.
Link .codex/AGENTS.md, retire goal.md, and make Codex delegate by name
Run `specnaut upgrade`. `.codex/AGENTS.md` becomes a link to the root
AGENTS.md, which Codex already reads; `.codex/goal.md` is removed if
untouched; `.codex/config.toml` gains `enabled = true` in its [agents] block.
If the report keeps `.codex/goal.md` because it was customized, show the user
its prompt and say Codex's `/goal` never read that file: propose using the
prompt as `/goal <objective>` directly, then deleting the file. If the report
says `.codex/config.toml` was left untouched because it already has an
[agents] table, show the four keys it lists and propose adding them to that
table.
Link .claude/CLAUDE.md to the root AGENTS.md
Run `specnaut upgrade`. `.claude/CLAUDE.md` becomes a link to the project's
root AGENTS.md (or, where links are refused, a one-line `@../AGENTS.md`
import), so AGENTS.md is the file Claude Code loads. If the report lists
`.claude/CLAUDE.md` under "replaced with a link to AGENTS.md", the old file
was customized and is in `.claude/CLAUDE.md.specnaut.bak`: show the user the
lines in it that AGENTS.md does not already say, and propose adding them to
AGENTS.md, outside the Specnaut-managed sections. Do not restore the backup
over the link. If the report says the file was a link git checked out as
text, tell the user git will show a type change there and either form works.
Carry the backlog pointer, the integrations and the agent per step in AGENTS.md
Run `specnaut upgrade`. It adds two Specnaut-managed sections to AGENTS.md,
"Backlog" and "Optional integrations", and a table naming the agent for each
step of the chain. If AGENTS.md still has an unfenced line that starts with
"**Backlog references** follow the `backlog-reference-contract` skill" above
the managed sections, propose deleting it: the "Backlog" section now carries
it. Change nothing else in AGENTS.md.
Plan a context link from what is on disk, and say what was written
No action for this change on its own: `specnaut upgrade` can now replace a
context file with a link, but no template asks for one until the commits
that link `.claude/CLAUDE.md` and `.codex/AGENTS.md`. Follow their adoption
steps.
Write a context link, or its fallback, and read one without following it
No action for this change on its own: the writer and reader can now make and
inspect context links, but no template asks for one yet. Follow the adoption
steps of the commits that link `.claude/CLAUDE.md` and `.codex/AGENTS.md`.
Model a context link and classify what is on disk at one
No action for this change on its own: it adds the model the later context-link
commits use, and writes nothing to the project. Follow the adoption steps of
the commits that link `.claude/CLAUDE.md` and `.codex/AGENTS.md`.
Internal / chores
20 internal changes
- Keep the pre-4.1 sections in docs/upgrading/
- Move the relink apply and the lock shape out of execute()
- One exhaustive ownership rule; one backup definition
- 7.0.x → 7.1.0 — context links, goal.md retired, Codex agents enabled
- Rewrite AGENTS.md — the working contract, and pointers to the authoritative lists
- Aim the altered-file mutant at AGENTS.md
- The no-root-CLAUDE.md check joins check_context_file
- Split renderMarked's marker handling out of its loop
- Split carryRenamedDocs into its selection and its byte move
- Split rebuildEntries' per-dest decision into entryFor
- One home for the context-file checks
- Move the CLI-surface tests out of init_test and reuse the shared reader fake
- Separator-independent link assertions for the Windows leg
- Move backups and the context-link writer out of the bundle writer
- One marker renderer for the four conditional families
- One home for what installed.lock hashes
- Extract the upgrade summary, init's backlog config, and the write report
- Move the upgrade action vocabulary into its own module
- Split the upgrade use case into single-purpose modules
- Move the bundle-option space into its own module
Full changelog: v7.0.3...v7.1.0