Repository navigation
Truth Rules
The truth check of nself-ci keeps false facts out of a repository. It reads rule files, scans the files of the repository and reports every line that breaks a rule. It never touches the network. The engine is free/ci/internal/gates/truth; the org rules are data in .github/truth/.
| File | Holds | Kinds |
|---|---|---|
.github/truth/org.yaml |
dead hosts, retired terms, banned literals |
dead-host, retired-term, banned-literal
|
.github/truth/claims.yaml |
hand-typed counts, current-version literals, retired vocabulary |
numeric-claim, version-claim, plus two vocabulary rules |
The claim kinds live in their own file so that a pinned nself-ci release that predates them keeps parsing org.yaml. A repo lists claims.yaml only after its pinned release carries the claim kinds.
A repo enforces the rules with .nself/ci.yaml:
version: 1
checks:
truth:
rules: [.github/truth.yaml]and a .github/truth.yaml that includes the vendored org rules and adds its own exemptions:
version: 1
include: [.github/truth/org.yaml, .github/truth/claims.yaml]
overrides:
claims.current-version:
facts: .github/facts.json
exempt_paths:
- {glob: "docs/history/**", reason: dated notes keep the version that was current then}All rule files are version: 1. A rule has id, kind, message (what to write instead) and optional paths (globs; default every file). Unknown keys, duplicate ids, bad patterns, exemptions without a reason and rule files outside the repository are E644 and name the file and key.
| Key | Kinds | Meaning |
|---|---|---|
pattern |
numeric-claim, version-claim | RE2, matched case-insensitively against one line. Required, with paths. |
facts |
version-claim | Repo-relative JSON or YAML file with a top-level version. A literal equal to it passes (a leading v is ignored). |
exempt_paths |
all |
[{glob, reason}]: files the rule skips. |
exempt_matches |
all but dead-host |
[{regex, reason}]: a hit inside a match of the regex is exempt. |
exempt_regions |
retired-term, banned-literal |
true makes the rule honour the markers below (the claim kinds always do). |
term ending in (s)
|
retired-term | Matches with and without the plural s. |
A reason has at least 8 characters.
A claim rule (and a vocabulary rule that sets exempt_regions: true) skips a hit that sits in:
- A generated region:
<!-- BEGIN GENERATED:<id> -->to<!-- END GENERATED:<id> -->(in.mdx:{/* BEGIN GENERATED:<id> */}). Both markers must be present; an unclosed or repeatedBEGINexempts nothing. - A JSX expression
{...}in an.astroor.mdxfile. Braces must balance within a paragraph, inline code and code fences do not count, and an expression that is only a quoted string or a template literal without${}is typed text, so it is not exempt. In.astrofiles the frontmatter,<script>and<style>blocks are code and are skipped. - The line after a comment that is the whole line:
<!-- truth: exempt <reason> -->(in.mdx:{/* truth: exempt <reason> */}). Text that merely mentions the marker, in prose, inline code or a fence, exempts nothing. A comment with no reason (fewer than four letters or digits) is a finding (truth.exempt-without-reason) and exempts nothing. - A file with a comment in its first three lines that says
GENERATED BY(its generator gates it).
Claim rules never read Go source, go.mod, go.sum or go.work, and skip changelogs, release notes (release-notes/, releases/v*), blog posts (content/blog, blog/*.md), ADRs, history folders, testdata, vendor and node_modules by default. They apply to prose paths only: Markdown, MDX, Astro text, README*, text files, i18n JSON values and packaging descriptions.
Known limits: the rules read one line at a time (a count split over two lines is missed), do not look through zero-width characters, miss a count written as Plugins: 62, all 62 free and paid plugins, 62 <b>plugins</b>, with a dash between the number and the noun, or in full-width digits, and do not read .tsx/.jsx text or .astro frontmatter strings; a file that is binary, UTF-16 or over 4 MiB is skipped and counted. A dead host is never printed: another rule's match or a file name that holds one is replaced by a redaction note.
A rule file may carry an overrides block keyed by rule id. It adds exempt_paths (and, for a version-claim, facts) to a rule declared in that file or in a file it includes, directly or not. An override that names an unknown rule id, or a rule the file does not include, is E644. facts is resolved against the scanned root, and a facts file reached through a symlink out of the tree is refused.
| Id | Kind | Catches | Write instead |
|---|---|---|---|
claims.counts |
numeric-claim | a count of plugins, commands, verbs, bundles or integrations | render it from the generated facts, or use words |
claims.counts-ar |
numeric-claim | the same count in Arabic i18n values (Western or Arabic-Indic digits) | render it from the generated facts |
claims.current-version |
version-claim | a version typed next to "nself" or "current/latest release" | render it from the facts file |
vocab.pro-plugin |
retired-term | the retired phrase for licensed plugins | "licensed plugin(s)" |
vocab.bundles-repo-slug |
banned-literal | the old name of the Bundles repository | nself-org/bundles |
vocab.bundles-repo-slug exempts Go module paths (exempt_matches): renaming a module path is a breaking change and GitHub redirects the old name.
Examples (each line below is exempt from the rules it shows, so this page stays clean):
- fails:
We ship 129 free plugins.
- passes: a line preceded by
<!-- truth: exempt a quoted line from the 2019 launch post -->
Human mode prints one line per finding, then the rule's message:
truth: <rule-id> <file>:<line>: <match>
fix: <message>
A dead-host finding prints a hash prefix, never the host. --json prints one document with data.result (pass, fail, error), per-check results and the findings.
From free/ci of this repository (the plugin binary does not link the check until the V15 engine does):
go run -mod=vendor ./internal/gates/truth/run.go check --root DIR [--json] [--kind K|rules] RULEFILE...Exit 0 pass, 1 findings, 2 rule-file or scan error. --kind rules validates the files without scanning.
bash scripts/truth/vendor-rules.sh TARGET_DIR # writes TARGET_DIR/.github/truth/{org,claims}.yaml
bash scripts/truth/vendor-rules.sh --check TARGET_DIR # exit 1 when a copy is missing or differsEach copy starts with # VENDORED FROM nself-org/plugins@<sha> — DO NOT HAND EDIT, then this checkout's bytes unchanged. --check ignores the header line. The truth-sweep drill runs --check on every public clone that carries .github/truth/, so a drifted copy fails the nightly sweep.
- Commands
- File Processing Commands
- GitHub Commands
- ID.me Commands
- Jobs Commands
- Notifications Commands
- Realtime Commands
- Shopify Commands
- Stripe Commands
View All: Home (or see the full alphabetical list below — 129/129 synced with registry.json)
- Access-Controls
- Admin-Api
- AI-CLI
- AI-Studio
- Alerts
- Analytics
- API
- Audit
- Audit-Analytics
- Audit-Log
- Auth-Enterprise
- Backup
- BYOK
- CDC
- CDN
- CI
- Claw-CLI
- Cloudflare
- Compliance
- Content-Acquisition
- Content-Progress
- Content-Safety
- Costs
- CRDT
- Cron
- DDNS
- Devices
- DLQ
- Documents
- Dogfood
- Donorbox
- DR
- E2EE
- Encryption
- Entitlements
- Event-Bus
- Family-Ancestry
- Family-FamilySearch
- Family-GEDCOM
- Family-MyHeritage
- Family-WikiTree
- Feature-Flags
- Federation
- File-Processing
- Flags
- Forgejo
- Functions-V8
- Game-Metadata
- Gateway
- Gauth
- GDPR
- Geocoding
- GitHub
- GitHub-Runner
- HIPAA
- Home
- IDme
- Infra
- Invitations
- Job-Queue
- Jobs
- K8s
- Link-Preview
- Maintenance
- MDNS
- Media-Processing
- Meetings
- MLflow
- Model
- Monitor
- Monitoring
- Notifications
- Notify
- nSelf-Cloud
- nSelf-Eval-Gate
- nSelf-Geo
- nSelf-Image
- nSelf-PDF
- nSelf-Scan
- nSelf-Sync
- nSelf-Vault
- Object-Storage
- Observability
- Ollama
- Payments
- PayPal
- Pentest
- Pentest-Kit
- Plugin-ClawDE
- Plugin-Gauth
- Plugin-LLM-Gateway
- Plugin-PTY
- Plugin-Retrieval
- Podcast
- Post
- Push
- Queue
- Region
- Release
- Retro-Gaming
- Rom-Discovery
- Search
- Sentry-CLI
- Shared-Utils
- Shopify
- SIEM
- SMS
- Soak
- Sports
- Storage
- Stripe
- Subtitle-Manager
- Tenant
- Tenant-Controller
- TMDB
- Tokens
- Torrent-Manager
- Traefik
- Transactional-Email
- VPN
- WAF
- Watchdog
- Web3
- Webhooks
- Workflows
Related