setup-repo
Skill1 starsChanged 19 days agoMITView on GitHub
Set up a new or legacy repo — the whole Cortex loop in one pass (root brief, verification, PR review, hooks, evals, agent team) or a report only. Asks once, edits no source. Triggers — "install cortex", "set this repo up", "onboard this project", "just index this", "show me the findings", or a repo with no AGENTS.md.
12 other projects use a version of this.
Adopted by
Most recently taken up by
- protokol11/skillstheir own version, first seen Nov 8, 2026
- mblauberg/provenanttheir own version, first seen Nov 8, 2026
- etr/groundworktheir own version, first seen Nov 8, 2026
- Significant-Gravitas/AutoGPTtheir own version, first seen Nov 4, 2026
- p-chan/agent-skillstheir own version, first seen Nov 1, 2026
- p-chan/skillstheir own version, first seen Nov 1, 2026
Used with
Projects with it also use implement.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Hugging FaceSkillimplement
Make tests pass. Invoke after /write-tests produces failing tests.
Also in 3 projects that use this
Other versions12 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 12
- Significant-Gravitas/AutoGPT★ 188ksame name
- etr/groundwork★ 45same name
- florian101010/awesome-agentic-AI-coding-template★ 4same name
- jpoindexter/theft-kit★ 1same name
- mblauberg/provenant★ 1same name
- nhhthong/skills★ 1same name
- protokol11/skills★ 1same name
- Sassy-Dog/skills★ 1same name
- vincenzo345/skills★ 1same name
- p-chan/agent-skills★ 0same name
2 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository43 other files it gives its agents.
- AGENTS.mdAGENTS.md
- core/AGENTS.mdAGENTS.md
- evals/AGENTS.mdAGENTS.md
- index/AGENTS.mdAGENTS.md
- mcp/AGENTS.mdAGENTS.md
- tools/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- architecture-reviewSkill
- audit-notesSkill
- challenge-planSkill
- change-impactSkill
- clarify-requestSkill
- connect-mcpSkill
- create-teamSkill
- daily-planSkill
- debug-issueSkill
- define-termsSkill
- design-specSkill
- end-of-day-summarySkill
- handover-notesSkill
- join-teamSkill
- merge-workSkill
- migrate-legacy-engineSkill
- personal-setupSkill
- quick-noteSkill
- register-projectsSkill
- repo-mapSkill
- resolve-conflictsSkill
- resume-workSkill
- retrospectiveSkill
- review-changeSkill
- set-profileSkill
- story-mapSkill
- suggest-skillsSkill
- summarize-filesSkill
- sync-websiteSkill
- trim-agent-docsSkill
- update-pluginSkill
- weekly-reviewSkill
- whats-changedSkill
- write-agent-docsSkill
- write-area-briefSkill
- write-context-docsSkill
The file
We split this skill into the rules it gives an agent
9 rules. 0 are common, 4 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 10 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 44
Read RUNS.md before step 1 in any of these cases:
- Very specific: line 181
Agent docs that were already here go first: If CLAUDE.md, .cursorrules or another agent doc exists and CONTEXT.md does not, a human wrote …
- Very specific: line 189
When it is there, the first question is whether to slim that doc with /trim-agent-docs before the scaffold runs.
- Very specific: line 352
Never invent a command: Every {{PLACEHOLDER}} that loop.mjs could not fill is a question for the user, not a blank for you.
- Very specific: line 358
Never clobber a curated file: If AGENTS.md or REVIEW.md exists with real content, write <name>.generated.md beside it and say to diff.
- Distinctive: line 364
Every row above that lands a whole file is written by the CLI, not filled by hand.
- Very specific: line 368
Put the values you decided in a JSON object in the OS temp dir, for example { "TEST_CMD": "npm test", "SETUP_STEPS": "" }.
- Distinctive: line 413
If the check still fails on a file you wrote, fix that file: If you cannot, report the failure with its output in step 8.
- Distinctive: line 430
If it warns not re-renderable, the file holds lines its values do not produce, usually because the formatter rewrote them.
“Common” is measured: kept by at least 6 in 10 of the 10 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/setup-repo — one install, working project or new one
The front door. Runs in a target repo, never in the Cortex repo itself.
Everything Cortex used to ask a user to sequence by hand — index, findings, scaffold, briefs, skills — happens here, in one pass, behind one confirmation. The other rituals still exist and are still callable by name; what changed is that nobody has to know their order to get a served repo.
One pass writes everything that can be written today. Two rows cannot be: evals need real past
tasks to seed cases from, and bands need a production metric with a stable history. Both also
wait on files this same pass writes (CLAUDE.md, REVIEW.md), so they come back as missing
afterwards. Say that in the playback. Do not promise them in the first pass. cortex-next.mjs then
names /setup-repo evals and /setup-repo bands (RUNS.md).
The rule that governs this whole skill: steps 1–5 read, report and ask. They do not modify one line of the repository. Writing happens in step 7, only for what the user confirmed. If you find yourself editing a file before the user has chosen something, stop — you have left the skill.
What "served" means here
A repo is served when the artifact chain is closed: an idea becomes intent.md, which becomes
spec.md, which becomes plan.md, which becomes a diff with tests, which becomes a PR judged
against a written policy, which passes a gate — and production writes the next intent.md.
Plan Design Build Test Deploy Maintain
intent.md → spec.md → plan.md → the diff → the PR → the breach
↑ │
└───────────────────────────────────────────────────────────┘Each stage ends by committing a file the next stage reads, which is why "is this repo served" is a
question about files on disk and not a judgment call. index/lib/loop.mjs answers it.
Report only, invoked with a row, or run unattended
Read RUNS.md before step 1 in any of these cases:
- Report only — "just index this", "report on this repo", "show me the findings". Index, report
and walk the offers, then stop; nothing is written beyond
.cortex/. This is what the separate install command did before 3.0.0. - Invoked with a row —
/setup-repo evals,/setup-repo bandsor/setup-repo team. Only that row is taken, and evals and bands stop when there is no real history to build them from. - Run unattended —
claude -p, where nobody answers the consent gate or step 6. Claude Code refuses every write under.claude/there unless the run is in auto mode, and the install still reads as finished.
1. Orient
node "${CLAUDE_PLUGIN_ROOT}/tools/cortex-preflight.mjs"Root, profile and index freshness, from the one place that owns them. Do not re-derive any of the three — every prose copy is a copy that drifts.
Refuse to continue if this is the Cortex repo itself (.claude-plugin/plugin.json names cortex).
Cortex installs into other repos.
The consent gate
This skill is model-invocable — you may start it yourself when a repo plainly needs it. That makes the gate below the thing protecting the repository, not the invocation rules.
If .cortex/ does not exist, ask before writing anything — including the index. Say what you
propose to do, and what the read steps write: files under .cortex/, plus three ignore lines
appended to .gitignore the first time. They never write to source. Then wait for a yes. Generated and gitignored is not the same as invisible: these are files appearing in someone's
project on a run they did not ask for.
If .cortex/ already exists, Cortex is established here and re-indexing needs no ceremony.
The gate is on the first write, not on reading. Orienting yourself — reading AGENTS.md, the
tree, the manifest — needs no permission and never did.
2. Index
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-index.mjs" .Deterministic and offline. Writes .cortex/index/index.json. The run that first creates .cortex/
also appends .cortex/index/, .cortex/findings/ and .cortex/view/ to the target's .gitignore,
and creates that file if there is none. That is the one write outside .cortex/. The indexer
prints the lines it added; tell the user.
Index before reading the loop. Two loop rows cite the index — the root brief names the detected stack, the hooks row names the generated paths — and without one they report "nothing detected", which a user cannot tell from "looked and found none". Running the loop first is not wrong, it is just half an answer, and it will say so in its own header.
The fork: working project or new one
The indexer prints the file count, and zero files is the greenfield flow — a different sequence, not a degenerate case of the other:
- New project — nothing to analyse, so skip the ceremony. Interview for the stack and the
commands instead of reading them, since there is nothing to read them from. Offer no scoped
briefs and no enrichment: both describe code, and there is none. Offer no
REVIEW.mdyet either — a review policy about nothing is a file that will be wrong by the time it is read. Say the honest version: the loop now grows with the code instead of being reverse-engineered from it. - Working project — continue below.
The fork is on the index, never on a guess. A repo with a README and no source is greenfield; a
repo whose only code is a build script is not. And an index that has not been built is not evidence
of either — loop.mjs refuses to call a repo greenfield on a missing index, because the first run
of this module announced "no code yet" over several hundred files.
3. Report what is wrong
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-findings.mjs" .Writes exactly one file, .cortex/findings/<date>.md. Read it, then give a short summary in
chat — the top three or four, most severe first, in your own words. Do not paste the report.
Lead with critical security findings if there are any, and say in the same breath that some will
be fixtures. A false positive presented as a breach destroys trust in every other finding.
4. Read what is missing
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-loop.mjs" . --jsonWrites nothing. Returns three buckets, and the difference between them is the whole interview:
| Bucket | Meaning | What you do |
present | already on disk | report it as served; never offer to rewrite it |
missing | applies here and absent | this is the worklist |
blocked | does not apply yet | name it, with its needs |
Walk missing in the order it comes — the rank is control flow, so the first row is the first
question. Each entry carries why (what was detected) and brief (what the body must contain).
A blocked row is named, never dropped. bands.yaml waiting on REVIEW.md is a fact the user
should hear once; an offer that silently vanishes is indistinguishable from a bug. One line each,
with the needs attached, and move on.
Never offer to overwrite a present artifact. A hollow REVIEW.md still counts as present,
because silently replacing a file someone wrote is the worse failure. If one looks thin, say so as
an observation and let them ask.
5. Also walk the findings worklist
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-findings.mjs" . --offersThis prints the ranked worklist as JSON and writes nothing at all. It is the same analysis the
report renders, in the shape you can act on: one entry per action, most severe first, each carrying
targets (what it would touch) and findings (the titles that produced it). It covers what the
loop does not:
| Action | Ask about |
scaffold | the context layer: AGENTS.md and shims, CONTEXT.md, docs/adr/ |
brief | scoped AGENTS.md leaves for the named areas |
bundle | the plugin tiers the index gave a reason for, never the whole list |
enrich | semantic summaries over the index |
memory | a committed .cortex/memory/ |
triage-secrets | nothing. See the rules below |
Merge it with the loop worklist into one list of questions; the user should not be able to tell
which module produced which. Say first that nothing is written until the end, and record yes, no
or later for each. Ask with the why from findings attached, and do not re-expand the
collapsed worklist per target: one brief entry is one question naming its candidates. An empty
worklist, or a user who declines everything, is a complete run.
On a team's repo, the person's job shapes the answers you propose, never the order or the
list. Read RUNS.md before step 2 when .cortex/connector.json exists.
Agent docs that were already here go first. If CLAUDE.md, .cursorrules or another agent
doc exists and CONTEXT.md does not, a human wrote it before Cortex arrived. Ask cortex-next.mjs
rather than re-deriving it — a reconcile step in its --json output is the signal:
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-next.mjs" . --jsonWhen it is there, the first question is whether to slim that doc with /trim-agent-docs
before the scaffold runs. Scaffold never clobbers a curated file, so skipping this does not lose
anything — it leaves the user with their file plus an AGENTS.generated.md to merge by hand,
which is the double-file a single install exists to avoid. The first version of this skill left
the step out and produced exactly that.
A reconcile step with optional: true is a different case: the layer is already written, and the
files in its docs (today only .github/copilot-instructions.md) still hold rules of their own
beside AGENTS.md. Add it to the worklist as one ordinary row that offers /trim-agent-docs for
those files. It is not asked first, and a no is a full answer: a team may keep rules for one tool
on purpose.
Skills an earlier pass wrote are checked on every re-run. A skill-drift step in the same
--json output lists each skill the repo now contradicts, with its lines in drift[].findings —
a path that is gone, "no tests" beside a test suite, a script no manifest declares. Every line is
provable from disk. Add each drifted skill to the merged worklist as one row naming its lines, so
the single confirmation in step 6 covers exactly what the user saw. When drift[].editedNote is
set, a person worked on that skill after it was written: put the note on the row, word for word.
The confirmation then covers the edit too, and nothing is asked about that skill afterwards. present in the loop means the
file exists; it never meant the file is still true.
Loop files an earlier pass stamped are checked against this release's templates.
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" . --jsonIt writes nothing. When olderPlugin is not null, a newer Cortex stamped this repo: say its
advice and offer no stamp row. This pass then updates no file and asks about none. Every state
below is measured against this plugin's older templates, so none of them is what the updated plugin
will find: a file that reads update here may read current there. So do not list the files or
their states, not even as a preview of what the pass after the update will offer or ask. A preview
is a promise about a comparison nobody has made yet, and that pass reads them again. A user who says
to just update everything gets the same answer. Updating the plugin is how everything gets updated.
files is null when there is no .cortex/stamps.json yet. Otherwise each file has a state, and
the state decides the row:
| State | Row |
update | one row, Update N files Cortex stamped: the template changed and the file is untouched |
review, conflict | one row per file, with its diff shown; never covered by [a]ll |
missing | ask whether to stamp it again or drop it (cortex-stamps.mjs forget . <path>) |
retired | name it; nothing to update it from. Drop it with forget if they agree |
edited | nothing. The team changed it and the template did not, so it is theirs |
adopt is non-empty | one row, Adopt N loop files an earlier Cortex stamped. It covers a repo installed before the record existed. On yes, run node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" adopt .. That writes the record only. The playback lists this one row and no file under it, because no diff exists before the record does. Each file then reads conflict, and step 7 offers to go through them once the record is written |
Get each diff from the CLI. It compares the file now with this release's template, filled with the
recorded values: node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" diff . <path>.
The team section in CLAUDE.md is not in the record, so it is checked against every text Cortex
shipped: node "${CLAUDE_PLUGIN_ROOT}/index/cortex-section.mjs" . --json. TEAM.md holds its rows.
When ignored is not null, the record this pass writes would be hidden from git, so the team
would never share it. That can be true before any record exists. Add one row that offers the
advice it carries. Edit .gitignore only if the user picks that row.
The agent team is asked role by role. The team row carries state.agentTeam: each role on
offer is its own yes/no, withheld roles are named with their reason, the verifier's upgrade is
one more yes/no, and each agent's proposals are asked one agent at a time with the diff, never
under [a]ll. Read TEAM.md before asking; it holds the questions and the writing.
Three rules survive the merge intact:
bundleis asked only about tiers this machine lacks. The worklist comes from the index, and the index never reads the machine, so a tier intargetsmay already be installed. Before the question, runnode "${CLAUDE_PLUGIN_ROOT}/mcp/ai-os.js" setup-plugins --status --json. It reads Claude Code's plugin registry and writes nothing. Drop each target whose tier hasstateinstalled, and for apartialtier name the plugins it still lacks. When no target is left, leave the row out and say in one line which tiers were already installed.unknownmeans there was no registry to read: ask about every target.enrichstates its token cost before the question, not after. It is the only offer that spends real money, and a user who says yes and then learns the price has been sold something.triage-secretsshows and stops. Present the possible secrets, say some will be fixtures, and take no remediation action — not rotation, not redaction, not a commit. It is a finding to hand over, not an offer to accept.
6. One playback, one confirmation
Play back everything as a list of paths, grouped by stage. Take one confirmation for the whole set:
Cortex will write, in one pass:
Plan intent/README.md, intent/TEMPLATE.md
Build AGENTS.md, CLAUDE.md, GEMINI.md, CONTEXT.md, docs/adr/
src/billing/AGENTS.md, src/api/AGENTS.md
Test CLAUDE.md § Verifying your work, .claude/agents/verifier.md
Team [x] architect [x] tester (+ .claude/hooks/test-paths.sh) [ ] implementer
.claude/skills/team/SKILL.md, CLAUDE.md § Working as a team
changes: every later session here stops before a code task and asks
"Single agent or team?", and plans or edits nothing until you answer
Deploy REVIEW.md, .github/workflows/cortex-review.yml,
.claude/settings.json, .claude/hooks/protected-paths.sh
Refresh .claude/skills/type-check/SKILL.md — lines 8, 55 (no tests; a moved path);
edited since it was written, 2 commits
Update .claude/hooks/protected-paths.sh, CLAUDE.md § Working as a team (templates changed)
Ask each REVIEW.md — you edited it and its template changed (diff shown above)
After this pass, waiting on history:
evals — cases are real past tasks; /setup-repo evals once there are some
bands.yaml — one metric with a stable history; /setup-repo bands, or never
Not now: enrichment (later), the plugin bundle (no)
[a]ll [p]ick a subset [n]oneA row that changes more than its files says so. A worklist row with an effect gets that
sentence under its paths, as the Team row above shows. A path does not tell the user that the
playbook changes how every later session starts, and a yes to something they were not told is not
consent.
Name the ADR directory the scaffold will use. It is docs/adr/, or adr/ when docs/ is a
published site (/write-context-docs step 3).
[a]ll is offered first and on purpose: a user who wants the whole loop should not have to answer
eight questions to get it. [p]ick drops back into the worklist one row at a time. [n]one is a
complete and successful run — a repo that was already served, or a user who wanted to see the gap
and not close it, has been served either way.
This is the single gate between deciding and doing. Not one per file, not one per stage. A user who has answered the worklist and is then asked again for each path has been interviewed twice.
7. Apply — one pass, in worklist order
Hand off wherever a ritual already owns the logic. Do not reimplement it here; the duplicate is what drifts.
| Item | Who writes it |
root brief, shims, CONTEXT.md, docs/adr/ or adr/ | /write-context-docs — it owns the templates, the never-clobber rules and the ADR location |
scoped AGENTS.md leaves | /write-area-brief, once per area they picked |
.claude/skills/ | /suggest-skills, from index.stack |
| a drifted skill | /suggest-skills § Refreshing a skill that drifted — the flagged lines only, and it asks again before touching a skill someone edited |
| the plugin bundle | node "${CLAUDE_PLUGIN_ROOT}/mcp/ai-os.js" setup-plugins --tier <tier> --scope user, once per tier they picked. /connect-mcp is the same step typed by a person |
.cortex/memory/ | create it, and say it is committed on purpose |
the team plugin (team-plugin) | node "${CLAUDE_PLUGIN_ROOT}/index/cortex-shared-plugin.mjs" . --write. It merges and refuses a file that does not parse; never hand-edit the JSON |
team-plugin is offered only on a team's repo: the work profile or a team-brain connector. Its
offer says what committing it does not do: once a teammate trusts the folder, Claude Code registers
the marketplace, but each teammate still installs once with claude plugin install cortex@cortex --scope project.
Auto-update is its own yes/no in the confirmation, unticked by default: [ ] auto-update — every
teammate's Claude Code pulls new Cortex releases in the background. Only a yes adds --auto-update.
The loop artifacts are written here, from ${CLAUDE_PLUGIN_ROOT}/templates/loop/:
| Template | Lands at | Fill in |
verification.md | appended to CLAUDE.md | only commands loop.mjs detected; ask for any it did not. The opening comment is addressed to you, so leave it out |
verifier.md | .claude/agents/verifier.md | the run command |
REVIEW.md | REVIEW.md | the detected generated paths under out-of-scope, and the suggestion cap |
settings.hooks.json | merged into .claude/settings.json | merge, never replace — read the file first |
protected-paths.sh | .claude/hooks/ | the detected paths, as shell glob patterns |
format-changed.sh | .claude/hooks/ | one <glob>) <command> "$path" >/dev/null 2>&1 ;; line per entry in state.formatters; none if it is empty |
intent-README.md, intent.md | intent/README.md, intent/TEMPLATE.md | who accepts an intent |
agent-evals.yml | .github/workflows/ | {{TEST_CMD}} with the detected test command; replace the {{SETUP_STEPS}} line with the toolchain and install steps from the repo's own CI, at that indentation, or delete it if there are none; keep checkout pinned by SHA with persist-credentials: false, and use the SHA the repo's own CI pins if it has one; cases live in evals/cases/<name>/ |
cortex-review.yml | .github/workflows/ | {{CORTEX_REF}} with v plus the version in ${CLAUDE_PLUGIN_ROOT}/VERSION, so each PR runs the release that stamped it; keep checkout pinned by SHA with persist-credentials: false; leave it advisory, and tell the user that setting the repository variable CORTEX_REVIEW_BLOCKING to true makes a provable broken citation fail the PR |
bands.yaml | repo root | one metric with a stable history, a read-only command, the rollback runbook |
team/architect.md, team/implementer.md, team/tester.md, team/reviewer.md, team/project-manager.md | .claude/agents/, one per role picked | the values from cortex-loop.mjs . --team <roles>, plus an answer to each of its needs (TEAM.md) |
team/test-paths.sh | .claude/hooks/ | the same values; only ever with tester.md |
team/team-skill.md | .claude/skills/team/SKILL.md | nothing to fill |
team/playbook.md | appended to CLAUDE.md | ROSTER from the same command: the team as picked, never edited by hand |
Never invent a command. Every {{PLACEHOLDER}} that loop.mjs could not fill is a question for
the user, not a blank for you. Cortex placeholders are bare {{NAME}}; a ${{ … }} in a
workflow file is GitHub Actions syntax and is left exactly as written. A CLAUDE.md telling an
agent to run npm test in a repo with no test script fails the first time it runs, and a context
file that is wrong once is not trusted on the parts the reader cannot check.
Never clobber a curated file. If AGENTS.md or REVIEW.md exists with real content, write
<name>.generated.md beside it and say to diff. .claude/settings.json is merged into, key by
key — replacing it takes out hooks and permissions somebody else depends on.
Stamp each whole-file row
Every row above that lands a whole file is written by the CLI, not filled by hand. One command renders the template, writes the file and records it, so the file is exactly what its recorded values reproduce. That is what lets a later release update it safely.
- Put the values you decided in a JSON object in the OS temp dir, for example
{ "TEST_CMD": "npm test", "SETUP_STEPS": "" }. The values are the detected commands, the user's answers, and the multi-line blocks such as CI steps or formatter lines. Two rules:- an empty value deletes a placeholder that sits alone on its line;
- a placeholder with no value is left as written, which is right only for
intent/TEMPLATE.md.
Stamp it:
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" stamp . <lands at> loop/<template> --values-file <json>It makes the folders, writes LF, and writes
.cortex/stamps.json. GitHub Actions${{ … }}passes through untouched. Never redirectrenderinto a file: a shell redirect can change the encoding, and nothing records it.- Exit 3 means it refused, and nothing was written. The file is already there and Cortex did
not record it, or the team edited it since. That is the rule above, kept by the command. Show
the user the diff and ask. On a yes, run it again with
--force; on a no, leave the file.
verification.md, playbook.md and settings.hooks.json are not recorded: two are appended to
CLAUDE.md and one merged into settings.json. Each is a block inside a file the team also writes.
Append a block with the CLI, never by hand: save the filled block to a file outside the repo and run
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-section.mjs" . --append CLAUDE.md --from <that file>. It
gives the block the line endings CLAUDE.md already has, so a CRLF checkout is not left with both
kinds, and it refuses a block whose heading is already there.
cortex-section.mjs tracks the playbook by its shipped texts instead. The
team-plugin entries are such a block too, and the CLI above writes them. Every other team file in
the table above is recorded.
Format what you wrote, then run the repo's own check
A stamped file has to pass the target repo's own checks. On the first real install it did not:
the repo's test script ran prettier --list-different, and ten files Cortex had just written
failed it. The format hook stamped in this pass only takes effect in the next session, so this
session has to format by hand.
- Write LF line endings in every file you create, whatever your checkout of the templates has.
A block added to a file that is already there takes that file's endings, which is what
--appenddoes. - Run the repo's formatter on exactly the files you wrote.
state.formattersin the step 4--jsonoutput lists what this repo declares, as{ glob, command }. Run<command> <file>for each file you wrote that matches a glob. Never run it on.: that reformats files you did not write, and nobody asked for that diff. - Run the repo's own lint/format check: the verification block's lint row, or the
format:check/lintscript the manifest declares. Then runnode "${CLAUDE_PLUGIN_ROOT}/tools/cortex-placeholders.mjs" <the files you wrote>, which exits 1 and names every template placeholder still left in them. - If the check still fails on a file you wrote, fix that file. If you cannot, report the failure with its output in step 8. Never edit the repo's formatter or lint config to make it pass. If no formatter is declared, say so; step 3 still runs.
Record what the formatter changed, and apply the updates
After formatting, record again each stamped file the formatter rewrote. stamp records a file
as it wrote it, so a formatter's rewrite reads as edited, as if the team had changed it.
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" . lists them. For each one from this pass,
with the same values file:
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" record . <lands at> loop/<template> --values-file <json>Record what is on disk now. The command writes .cortex/stamps.json and nothing else.
If it warns not re-renderable, the file holds lines its values do not produce, usually because the formatter rewrote them. It is still recorded, but a later template change will ask about it instead of updating it. Name those files in step 8.
Apply the Update row the user confirmed through the CLI:
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-stamps.mjs" update . <each confirmed path>It re-renders each file from its recorded values, records it again, and refuses anything not in
state update. Never re-render a stamped file yourself. A section in the row goes through
cortex-section.mjs . --replace <id> (TEAM.md); never edit CLAUDE.md by hand for it.
For each review or conflict file the user answered, apply their choice by hand, then record
it again.
After an Adopt row, offer the adopted files in this pass. Once everything else confirmed is
written, read cortex-stamps.mjs . --json again: the adopted files now read conflict. Say how
many there are and ask one question: go through them now, or leave them for the next run. On
"now", ask about each file by itself with its diff, as for any conflict file, and change only
what the user answers. On "later", name them under what was deferred in step 8. Either way no
adopted file is changed without its own answer.
8. Close
State what was written, as the same list of paths from step 6, so the promise and the result can be
read side by side — read back from disk, not from what you meant to write. Rerun
cortex-loop.mjs . --json: a confirmed row still in missing was not written, whatever your tool
calls looked like. If it carries a non-empty protectedWrites, Claude Code refused it — see
RUNS.md. Then state what was marked later, by name — a
deferred offer that goes unmentioned is a decision the user made and Cortex quietly dropped.
node "${CLAUDE_PLUGIN_ROOT}/index/cortex-loop.mjs" . --lineEnd with that one line, not a menu. It says what the loop is still missing or that it is closed,
and it is the last thing the user reads. A list of eleven commands sorted by nothing is where an
install stops being useful — they leave holding options instead of a step. If the line names
evals/ or bands.yaml, add one sentence saying what each is waiting for: task history, or a
metric with a history. Do not present it as work this pass left undone.
Then: suggest committing what was written so the team shares it, .cortex/stamps.json included (it
is how the next release's re-run tells the team's edits from Cortex's own), and mention /end-of-day-summary at the end of
a working day, because .cortex/memory/ is the only part of the loop that nothing on disk will
remind them about.
Gotchas
- Re-running is the supported path, and it is cheap. Satisfied rows come back as
presentand are not asked again; deferred ones come back asmissing. What an earlier pass wrote is kept, so a re-run looks again at whether a skill is still true (skill-drift), and whether a stamped file or a section inCLAUDE.mdis behind this release (the stamp record,cortex-section.mjs). Step 5. .cortex/index/and.cortex/findings/are generated and gitignored..cortex/memory/and.cortex/stamps.jsonare committed — that asymmetry is deliberate and worth explaining once.- A hook that asks a human belongs at the release gate, not the build. An approval prompt during implementation puts a person on the critical path of every session running in parallel, which is the bottleneck this whole loop exists to remove.
- The indexer resolves imports by convention, so dynamically loaded files look like orphans. Present orphans as "worth checking", never "safe to delete".
- On a monorepo, offer to run against one package rather than the whole tree when the top-level file count is very large. The commands are detected at the root, so a repo keeping its manifests one level down reports none — say that rather than inventing them.
Where the shape came from
The loop, the artifact chain and the six stages are Anthropic's AI-native SDLC playbook. The plays
Cortex stamps here are: capture as intent.md, requirements and design, plan mode, CLAUDE.md,
skills as institutional knowledge, the feedback loop, continuous evals, AI in the PR review loop,
hooks as approval gates, and closing the loop on metrics.
Two plays are deliberately not stamped, because they are decisions an install cannot make: parallel sessions (how many streams one person can review is theirs to find) and CI/CD deployment through MCP (which needs credentials and an environment Cortex must not touch).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

