Rule-naming standard
Every rule_id in a TruStacks overlay follows one naming standard. The same
regular expression, reserved list, and length cap are checked by the CLI, the
rule-drafting API, and the signing step, so an ID that passes one passes all
of them.
The full specification lives in the public trustacks-policy repository at
standards/rule-naming.md.
This page is the summary.
The shape
<namespace>.<name>- Lowercase letters, digits, and underscores. No hyphens, uppercase, or spaces.
- Exactly one dot between namespace and name.
- Each part starts with a letter.
9foo.baris rejected;foo9.baris fine. - 64 characters or fewer in total.
- Reserved namespaces belong to TruStacks:
argocd,constitution,posture,practice,proposal,trustacks.
The pattern is ^[a-z][a-z0-9_]*\.[a-z][a-z0-9_]*$.
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 # two dots
proposal.requires_runbook_link # reserved namespace
practice.requires_runbook_link # reserved namespace (since version 2)Recommended conventions
Not enforced, but they keep an overlay readable as it grows:
- Namespace = your workspace or org slug. One prefix for every rule you write.
- Name =
<verb>_<noun>in present tense:requires_<thing>fails when the thing is missing,denies_<thing>fails when it is present.
Where it is checked
| Surface | When | What you see on failure |
|---|---|---|
trustacks rule new <id> | Scaffolding a rule | An error naming the reason; exit code 1, nothing written |
trustacks rule test <id> and trustacks rule lint <id> | Scoping a run to one rule | Same error, exit code 1 |
trustacks rule lint | Every directory under rules/ | One issue per bad directory name |
/rule new <id> in Workspace chat | Starting a draft | A hint with an example ID |
POST /api/rule-drafts | Creating a draft through the API | HTTP 422 with the reason |
trustacks rule sign | Before anything is pushed | Signing stops; no bundle is published |
The constitution also carries the standard: constitution.overlay_rule_naming
and its data.naming.json hold the same pattern, reserved list, and cap, so
the rule set you are judged against states the rule you are named by.
The checks above all run through TruStacks tools. A bundle built and signed
some other way skips them, but the runner still drops any overlay rule
whose id is invalid, reuses a constitution rule id or uses a reserved
namespace from the rule inventory it reports (and logs it), and from 0.2.14
rejects an overlay whose packages are not under overlay.. Rules loaded
from your platform repo (runner 0.2.17 and later) get the same checks; see
the constitution page.
Versioning
Version 2 of the standard is active. It adds one rule for the rules
TruStacks ships: a constitution rule’s namespace must equal the directory it
lives in. Because every constitution directory is therefore a namespace,
version 2 also reserves practice and posture, which the constitution
already used but version 1 did not reserve. The grammar and the length cap
are unchanged, and overlay rule IDs that were valid under version 1 stay
valid unless they used practice or posture. The full text is the
rule-naming standard
in trustacks-policy.
Related
- Policy linter · everything
rule lintchecks - Rule CLI ·
rule new,test,lint,sign - Constitution · the rules your overlay adds to