Skip to content

Adopt Your Own Governance

Licensed commands. Every CortexBuild command except auth and the host-invoked hook requires a valid licence. If you see license required, run cortexbuild auth activate --key <token> (or cortexbuild auth refresh if a lease simply lapsed) and try again. --help always 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 new refuses 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 — render warns about it, and cortexbuild doctor reports 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 rules count 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:

  1. The procedure body becomes a rule — register it with rules new (prose + --severity works directly). The rule carries the knowledge.
  2. The orchestration becomes the skill — a steps: manifest that consumes: 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 disposition generated — "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 --ssot at 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

  1. Retire your generator's output once its content is safely triaged — stop it writing AGENTS.md, .cursor/rules/, and any other surface CortexBuild renders.
  2. 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.
  3. 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.
  4. 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:

  1. Prove it locally. Author with cortexbuild rules new (or agents new) in one repo until the rule is doing real work there.
  2. 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
  1. 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. render and cortexbuild doctor both report the id as inert-repo-local once that happens; that report is your signal it is safe to delete .cortexbuild/rules/foundational/<id>.md in 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".