Help us improve
Share bugs, ideas, or general feedback.
From exarchos
Guides authors through a 6-step interview to create architectural invariant catalog entries. Drives scaffold and add verbs for schema-validated YAML output. Use when an author says 'add an invariant' or 'enforce an architectural rule'.
npx claudepluginhub lvlup-sw/exarchosHow this skill is triggered — by the user, by Claude, or both
Slash command
/exarchos:authoring-invariantsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill turns an architectural rule in the author's head into a **registered,
Guides authors through a 6-step interview to create architectural invariant catalog entries. Drives scaffold and add verbs for schema validation and file writing.
Guides structured conversations to define repository architecture principles in clean (default), hexagonal/ports & adapters, modular monolith, or custom styles. Produces formal architecture.md document for project standards.
Encodes human-readable governance policies into machine-executable JSON constraints for AI agents and CI pipelines to validate automatically. Outputs rule files in .ai/governance/.
Share bugs, ideas, or general feedback.
This skill turns an architectural rule in the author's head into a registered,
enforced catalog entry. It is the on-ramp described in
docs/designs/2026-05-25-invariants-authoring-wizard.md — an LLM-driven
authoring conversation, not a stdin question loop.
The division of labor is strict and load-bearing:
invariants_scaffold
and invariants_add. You never hand-write or append catalog YAML
yourself. The verb renders it; you confirm it.This shape is the only one consistent with the agent-first philosophy: inputs are constrained at the schema level (INV-5a), mutating verbs default to dry-run (INV-5c), and authoring is event-sourced (INV-1).
check_invariant_conformance gate).| Action (MCP) | CLI facade | What it does |
|---|---|---|
invariants_scaffold | exarchos invariants scaffold | Create a starter catalog file for a tier; idempotently register it in .exarchos.yml. Never overwrites an existing file. |
invariants_add | exarchos invariants add | Validate ONE entry against the v3 schema (including the .strict() enforcement DSL — INV-4), then append it. dryRun defaults to true: returns the rendered entry + file diff, writes nothing. |
doctor | exarchos doctor | Reuse the existing invariants-catalog check — the validator. No new validate verb. |
invariants_effective | exarchos view invariants_effective | The merged, projected catalog the gate will enforce. Post-write confirmation. |
The agent never declares an entry valid on its own authority — the verb is
the validator. invariants_add returns the INV-5b carrier shape: success
carries next_actions (["doctor", "view invariants_effective"]); validation
errors carry validTargets / expectedShape / suggestedFix sourced from the
Zod error, so you can self-correct and re-run rather than re-guess.
Walk the author through these in order. Elicit in prose, never make them think in YAML field names.
summaryAsk the author to state the rule in one sentence. Distill it into a precise
summary. Probe for the failure it prevents ("what goes wrong if this is
violated?") — that sharpens both the summary and the later enforcement.
dimension, applies-to, affinitiesdimension: a free-text grouping (e.g. audit-completeness, error-handling).applies-to: the glob(s) the rule governs — ask the author to name the paths
(src/handlers/**, **/*.ts). These are author-named globs, never
framework-inferred (INV-6: the surface is workload-neutral).phase-affinity: phases where it bites (ideate | plan | delegate | review | synthesize). Absent ⇒ all phases.workflow-affinity: workflow types (feature | debug | refactor | discover | oneshot). Absent ⇒ all.severity, integrity-class, and the tier you author intoseverity.default: blocking or advisory.severity.by-workflow (optional): downgrade for cheap workflows
(e.g. oneshot: advisory).integrity-class (entry field; enum substrate | sdlc | authoring | user):
the entry's override authority, not its namespace. For a consumer-authored
rule this is user. (substrate/sdlc are exarchos's own classes — you do
not author those.)tier (the verb arg) picks the catalog namespace, and the choice is
exarchos-substrate vs project-authored, NOT "which developers". This is the
one that bites — get it wrong and you silently collide with exarchos's own ids:
tier: user → U-N ids — your project's own invariants. The default for
everyone consuming exarchos. If you are authoring a rule for your own
repo, this is always the answer (even if your project happens to name its
rules INV-N internally — they map to U-N here).tier: dev → INV-N ids — exarchos's own reserved substrate catalog.
Exarchos ships its own INV-1..6 inside the tool, and they merge into every
invariants_effective projection. Authoring into dev from a consumer repo
collides your INV-N with exarchos's own — a silent namespace clash the
doctor check can't catch (it only flags INV-* in a user catalog). Use
dev only when working inside the exarchos repo itself. The verbs
enforce this: invariants_scaffold / invariants_add reject tier: dev
outside the exarchos repo (heuristic: package.json name ≠
@lvlup-sw/exarchos) with a RESERVED_TIER error that redirects to user;
a genuine exarchos fork opts in with allowReservedTier: true.mode: audit, mode: check is opt-inDefault to mode: audit. You draft the audit-prompt from the elicited
rule — a question the review subagent answers against the diff. Audit mode is
pure judgment and always portable:
enforcement:
mode: audit
audit-prompt: >-
Does this diff let a request handler return before emitting an audit event?
Cite the offending file + line.
Offer mode: check only as an advanced opt-in when the rule is mechanically
checkable. If the author opts in, propose a declarative combinator tree over
grep/structural/heuristic leaves and validate it live via invariants_add
with dryRun: true before showing it. See @references/check-mode.md for the
combinator vocabulary and the opt-in flow. The enforcement DSL is .strict()
and declarative-only: there is no script / exec / code escape hatch
(INV-4), so you cannot emit an executable check even if asked.
Do not pick an id. invariants_add auto-assigns the next free id in the
target catalog's namespace (U-N for user, INV-N for dev). Mention the id the
verb assigned when you show the dry-run.
This step is a gate, not a formality. Always:
invariants_add with dryRun: true (the default). This renders the
entry + diff and writes nothing.invariants_add with
dryRun: false. This appends the entry, wires .exarchos.yml if the catalog
is unregistered, and emits invariant.authored (+ catalog.registered on
first registration — INV-1).doctor (the invariants-catalog check) to validate the resolved catalog.invariants_effective delta so the author sees exactly what the
gate will now enforce.If invariants_add returns a CATALOG_NOT_FOUND error, the target catalog does
not exist yet — run invariants_scaffold first (the error's suggestedFix
names the call), then resume at step 6.
Scaffold a user catalog (idempotent; never overwrites):
mcp__plugin_exarchos_exarchos__exarchos_orchestrate({
action: "invariants_scaffold",
tier: "user",
path: ".exarchos/invariants.md"
})
Dry-run preview (DEFAULT — writes nothing):
mcp__plugin_exarchos_exarchos__exarchos_orchestrate({
action: "invariants_add",
tier: "user",
catalog: ".exarchos/invariants.md",
entry: { /* the fields from steps 1-4; NO id — auto-assigned */ }
})
Commit after explicit confirmation:
mcp__plugin_exarchos_exarchos__exarchos_orchestrate({
action: "invariants_add",
tier: "user",
catalog: ".exarchos/invariants.md",
entry: { /* same entry */ },
dryRun: false
})
Use mcp__plugin_exarchos_exarchos__exarchos_orchestrate({ action: "describe" }) (or the CLI
--help) to discover the exact schema at runtime — flags auto-emit from each
action's Zod schema (the CLI is schema-driven; do not assume hand-added flags).
For one U-* entry authored end-to-end through all 6 steps, see
@references/worked-example.md.
| Don't | Do Instead |
|---|---|
Hand-write or Edit catalog YAML | Always route mutations through invariants_add |
| Declare an entry valid yourself | The verb validates; you confirm |
Default to mode: check | Default to mode: audit; check is opt-in (@references/check-mode.md) |
| Skip the dry-run | dryRun: true first, ALWAYS, then explicit confirm |
Silently re-invoke with dryRun: false | Make the confirmation step explicit |
| Pick an id by hand | The verb auto-assigns the next free id in the namespace |
Author into dev/INV-N from a consumer repo | dev is exarchos's reserved substrate namespace — use user/U-N (the verb rejects consumer tier: dev) |
| Infer globs from the framework | Ask the author to name the globs (INV-6) |
Skip doctor + invariants_effective after commit | Verify the resolved catalog and show the delta |