Rule-naming standard
Every rule_id in a TruStacks customer overlay follows the same
naming standard. The standard is enforced by the
Constitution at bundle-sign time (no
bundle ships with a malformed slug) and validated at every authoring
surface so you get friendly feedback long before you hit the gate.
The full specification and examples table live in the
trustacks-policy repository (Apache 2.0; flips public at Beta
launch on 2026-07-27). This page is a reference summary for daily
use.
The shape
A rule_id looks like this:
<namespace>.<name>- Lowercase letters, digits, and underscores. No hyphens, no uppercase, no spaces.
- Exactly one dot separating namespace and name.
- Leading character of each part is a letter.
9foo.baris rejected;foo9.baris fine. - 64 characters total or fewer.
- Reserved namespaces are off-limits to customer overlays:
proposal,argocd,constitution,trustacks.
Quick examples
Valid:
acme.requires_runbook_link
acme.requires_approvers_group
contoso.denies_public_ingressInvalid:
Acme.RequiresRunbookLink # uppercase
acme-corp.requires_runbook # hyphen
acme.security.requires_runbook # nested namespace
proposal.requires_runbook_link # reserved namespaceRecommended conventions
Beyond the grammar above, two conventions keep overlays readable as they grow:
- Namespace = your workspace slug. Use one prefix across every rule in your overlay. The TruStacks UI proposes a namespace from your workspace name by default.
- Name =
<verb>_<noun>in present tense. Common verbs that read naturally:requires_<thing>: fails when the thing is missingdenies_<thing>: fails when the thing is presentmandates_<thing>: same shape asrequires_, for process rulesforbids_<thing>: same shape asdenies_, for strong prohibitions
These conventions are recommended, not enforced; reviewers will likely ask you to rename if you stray far from them.
Where it’s enforced
| Surface | When it fires | What you see on failure |
|---|---|---|
trustacks rule new <id> (CLI) | When you scaffold a new rule | Rich-printed error; CLI exits non-zero |
/rule new (TruStacks UI) | When you type a command | Chat-turn hint with example slug |
POST /api/rule-drafts (Control Plane) | Direct-API + UI dispatch | HTTP 422 with structured error detail |
| Constitution | At trustacks rule sign time | Sign aborts; no signed bundle leaves the registry |
All four surfaces read the same regex + reserved set + length cap. A CI lockstep test in the product repo asserts they stay byte-identical across the canonical Python module + each consumer’s mirror.
The Constitution check is the load-bearing gate. Even a hand-edited
rule_metadata.yaml file that bypasses the CLI cannot ship in a
signed bundle.
Full specification
The canonical standard, including the auditor-readable rationale,
examples table, description-style conventions, and the versioning
plan, lives at standards/rule-naming.md in the trustacks-policy
repository. That repository is Apache 2.0 and flips public at Beta
launch on 2026-07-27; until then, this page is the accessible
reference.
That document is the source of truth. This reference page is a short summary maintained in lockstep with it.
Versioning
This is version 1 of the standard, the baseline. Future revisions
will declare a version number in the constitution bundle’s
data.naming.json sidecar so existing signed bundles continue to
verify against the version they were signed under.
Related
- Constitution: what the constitution is, how it’s signed, and where the rule-naming check fits.
- Runner CLI: the
trustacks rule new/test/lint/signflow. trustacks-policyrepository: the full standard plus community-contributed framework packs. Apache 2.0; flips public at Beta launch on 2026-07-27.