Principles — the authored guardrails the agent reads
Principles are authored markdown that informs the agent. They are guides, not
gates: a principle never blocks a transition (only a reviewer does that — see
satelle help reviewer-checks). What principles do is shape how work is done —
they are the order-zero context the executor carries.
Two layers: embedded vs repo
Like every authored kind, principles resolve in two layers:
- Embedded (canonical, in the binary) — the universal principles every
satelle repo inherits, shipped under
config/substrate/principles. These are the single source of those bytes; a repo never edits them. Current set:satelle-constitution,satelle-repo-agnostic,satelle-agent-goals,satelle-done-is-last,satelle-actor-model. - Repo (layered, under
.satelle/principles/) — a repo's own principles. A repo file with the same name overrides the embedded default; a new name adds to the set. The directory monitor (satelle index) syncs them into the doc index.
List them with satelle doc list --kind principles; read one with
satelle doc get principles <name>.
Residency: principles:always vs principles:global
A principle's frontmatter tags decide whether it is resident or on-demand:
principles:always— the resident set. These are injected into the agent's context at the start of every session and are meant to stay small (a handful of short, order-zero principles).principles:global— discoverable but not auto-injected. The agent pulls it on demand (satelle doc get principles <name>) when a task needs it. Use this for longer reference principles.
How the resident set reaches the agent (injection)
A Claude Code SessionStart hook runs satelle hook context. It collects every
principles:always doc, injects their bodies (bounded by a byte ceiling — an
overflow is reported on stderr, never silently dropped), and appends the standing
instruction to discover the rest via satelle doc list. It fails open: an
unconfigured repo or any read error injects nothing and never blocks the session.
Wire it once, in .claude/settings.json:
{ "hooks": { "SessionStart": [ { "hooks": [
{ "type": "command", "command": "satelle index" },
{ "type": "command", "command": "satelle hook context" }
] } ] } }
Run satelle hook context by hand to see exactly what a session would receive.
Authoring a principle
- Add a markdown file under
.satelle/principles/<name>.md(repo) — or, for a universal default, underconfig/substrate/principlesin the binary. - Give it frontmatter:
name,kind: principle, adescription, andtags. Tag itprinciples:alwaysonly if it is short and belongs in every session; otherwiseprinciples:global. - Link related principles with
[[other-principle-name]]. satelle index, then confirm withsatelle doc get principles <name>(and, for an always-principle, that it appears insatelle hook context).
The order-zero principles
satelle-constitution— satelle is a harness that runs your repo's process as configuration; the binary holds mechanism, the substrate holds behaviour.satelle-repo-agnostic— keep the product separable from the one repo that dogfoods it; configuration over code.satelle-agent-goals— drive a story to its terminal state through every gate; status is the sole proof of done; never route around a gate.satelle-done-is-last—doneis always the terminal state; gates precede it.satelle-actor-model— every step is run by a defined actor (executor does the work; reviewer is limited to read-only reviewing); each gate is an isolated fresh-context call; satelle gates status; process is configuration.
See also: satelle help reviewer-checks, satelle help create-story.
Mirrored from satelle’s built-in help. Read it in the binary with
satelle help principles, or see the canonical source in the
satelle repo.