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,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 namespaceRecommended 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. Overlay bundles have no delivery path to hosted runners yet; see the constitution page.
Versioning
This is version 1 of the standard. A version 2 that ties a rule’s namespace to the directory it lives in is in progress. Rule IDs already in use do not change.
Related
- Policy linter · everything
rule lintchecks - Rule CLI ·
rule new,test,lint,sign - Constitution · the rules your overlay adds to