Adopt Your Own Governance¶
Licensed commands. Every CortexBuild command except
authand the host-invokedhookrequires a valid licence. If you seelicense required, runcortexbuild auth activate --key <token>(orcortexbuild auth refreshif a lease simply lapsed) and try again.--helpalways works.
Teams arrive at CortexBuild with governance they already built — rule files, prompt runbooks, agent personas, sometimes a full SSoT-and-render system of their own. All of it can be adopted repo-locally, without an org standards pack and without the admin portal. This page is the supported path.
The three front doors¶
Each command is fail-closed: an invalid file or a colliding id is refused with the reason, and nothing is written.
| Artefact | Command | Lands in |
|---|---|---|
| Rule | cortexbuild rules new --id rule-<org>-<name> --from <file> |
.cortexbuild/rules/foundational/ |
| Skill | cortexbuild skills new --id skill-<name> --from <file> |
.cortexbuild/skills/ |
| Agent | cortexbuild agents new --id <name> --from <file> |
.cortexbuild/agents/ |
After registering, run cortexbuild render — the artefact reaches every
enabled tool surface (CLAUDE.md, AGENTS.md, .cursor/rules/,
.github/), is tracked in ownership.json, staged by the commit-set, and
survives cortexbuild upgrade.
Rules¶
- Ids must be your own. Precedence ranks bundled above org-standards above
repo-local, so a repo-local rule reusing a higher pack's id is silently
inert.
rules newrefuses the collision at authoring time and names the owner; prefix your ids (rule-acme-...) and this never bites. - Placement matters. The loader reads exactly
.cortexbuild/rules/foundational/(always-on) and.cortexbuild/rules/adaptive/(signal-activated,--adaptive). A rule file anywhere else under.cortexbuild/rules/governs nothing —renderwarns about it, andcortexbuild doctorreports it as a decision-needing state. - Prose imports. A runbook with no frontmatter registers with
--severity <critical|high|medium|low>; the frontmatter is synthesized around your body. - Verify every rule by outcome: the
Loaded N rulescount increments, and the rule id appears in the rendered surfaces (grep -rl <rule-id> CLAUDE.md .cursor/rules/).
Skills — and where a thick runbook goes¶
A CortexBuild skill is a thin manifest that composes governed artefacts: it
must carry steps: and must consume: at least one rule or agent. A
self-contained eight-phase procedure does not fit that shape, by design.
The supported decomposition for an imported prose runbook:
- The procedure body becomes a rule — register it with
rules new(prose +--severityworks directly). The rule carries the knowledge. - The orchestration becomes the skill — a
steps:manifest thatconsumes:the rule (and any agents it drives).
Order is load-bearing: rules land before the skills that reference them,
because skills new refuses an unresolved consumes: reference. A migration
naturally reaches for the skills first; do the rules first instead.
Agents¶
Agent files need frontmatter id, name, description (filename must equal
<id>.md). Precedence ranks bundled agents above an org standards pack above
your repo-local personas, so agents new refuses an id either of the first two
already owns — give your persona an id of its own. Registered agents are
counted in the render load line and their rendered copies name
.cortexbuild/agents/<id>.md as the editable source.
A persona dropped directly into a rendered output directory (for example
.claude/agents/<id>.md) instead of registered through agents new skips
every one of those checks and is invisible to the ownership manifest. render
reports it as a hand-maintained file and names the exact command
(agents new --from <file>) to bring it into the tracked pipeline.
If you already have your own SSoT-and-render system¶
Two systems writing the same surfaces means agents silently load both, and
plain cortexbuild adopt makes this worse, not better: its adapters are
adapter-format-driven, so against a mature homegrown estate — a canonical
source directory plus a generator that renders .cursor/rules/, AGENTS.md,
.github/copilot-instructions.md, .kiro/, .opencode/ and the rest — it
only ever sees the generated adapters, every one a build output, and would
propose staging them as policy while the real source stays ungoverned.
adopt --ssot <dir>: tell it where the real source lives¶
cortexbuild adopt --ssot .governance --dry-run # <dir> is your canonical source tree
With --ssot declared:
- Every known tool-surface adapter's output (
.cursor/rules/*.mdc,AGENTS.md,.github/copilot-instructions.md,CLAUDE.md,.clinerules,.windsurfrules, …) is reported with dispositiongenerated— "looks generated; source declared at<dir>" — and is not staged. Nothing from your generator's output ever lands in.cortexbuild/imported/. - The declared SSoT tree itself is staged at low confidence, disposition
needs-human, under.cortexbuild/imported/ssot/— for triage, never auto-imported as policy. Promote what you want through the front doors above (rules new/skills new/agents new), same as any other import. - More than 40 candidate files under the SSoT tree trips an interview
instead of a bulk stage: an interactive run asks which files to bring in; a
non-interactive run (CI,
--json, piped input) only reports the count and stages nothing from the tree, so a hundreds-of-files estate can't silently explode the rendered rule count. Point--ssotat a narrower sub-directory, or re-run interactively and select a subset.
Without --ssot: the cheap generator-banner sniff¶
Running adopt without --ssot still gets a cheap signal: a file whose
first five lines carry a "generated" / "do not edit" / "rendered from" banner
that does not name CortexBuild is reported with disposition
looks-generated — "is the source elsewhere? re-run with --ssot <dir>"
— and is not staged. A CortexBuild-rendered file's own banner (which always
names cortexbuild render / self-bootstrap / export) is never mistaken
for a foreign one.
This is a textual sniff over a handful of lines, nothing more: it catches the
common case (nearly every generator marks its own output), not full
content-similarity detection against every known adapter's rendered shape.
An unmarked generated file without --ssot still reports as ordinary
source and stages normally.
Every artefact carries a disposition¶
source | generated | looks-generated | needs-human — visible in the dry-run
table's Disposition column, in the one-line summary ("N source, M generated
(skipped), K need a decision"), and in every --json record.
Then, by hand¶
- Retire your generator's output once its content is safely triaged —
stop it writing
AGENTS.md,.cursor/rules/, and any other surface CortexBuild renders. - Merge overlaps by hand. Where your rule and a bundled rule cover the same topic, the bundled rule stays governing (it carries the principle); your estate's specifics go into a new-id repo-local rule. Deduplicating on topic name deletes the half that carries the knowledge.
- Reference catalogues (schema dumps, API inventories, architecture
references) stay outside the rule pack — inlining them would bloat every
surface. Register them instead with
cortexbuild reference add <path> --id ... --kind ... --description ...; see Reference Data for the full workflow, including the provenance/staleness check (cortexbuild reference check) and the short section every rendered surface gains once something is registered. - Secrets: adopt only the instruction to read credentials from a local environment file at runtime. Values never enter a governed surface — rendered files are committed and rendered everywhere.
Going org-wide¶
Repo-local first, always: prove the rules in two or three repos before distributing. Distribution across an estate is what org standards packs are for, and promoting a proven repo-local pack no longer means hand-copying rule files between repos or maintaining a separate git mirror by hand:
- Prove it locally. Author with
cortexbuild rules new(oragents new) in one repo until the rule is doing real work there. - Promote it. From that repo, run:
cortexbuild standards pack .cortexbuild/rules --dry-run
cortexbuild standards pack .cortexbuild/rules --pack-id <your-org-id> --publish
The first call validates every file and prints a table without publishing
anything; the second authenticates through the SAME admin session login the
portal uses — your own org-admin credentials, supplied via
CORTEXBUILD_ADMIN_USER / CORTEXBUILD_ADMIN_PASSWORD (set from your
secret store or a prompt, never typed inline where it lands in shell
history) — and imports the whole directory in one transactional call — one
bad file writes nothing, the rest of your pack included.
3. Pull it into every other repo:
cortexbuild standards fetch
cortexbuild standards sync
- Delete the local copies once they're inert. Once the org pack defines
the same rule id, precedence ranks org-standards above your repo-local
file — it still parses, it still sits on disk, but it can never again win
the merge.
renderandcortexbuild doctorboth report the id asinert-repo-localonce that happens; that report is your signal it is safe to delete.cortexbuild/rules/foundational/<id>.mdin the repos you promoted it from.
An admin portal is not required for any of this — standards pack --publish
is the CLI path to the same authoring surface the portal's Standards screen
offers under "Import from repo".