cli

package
v0.0.294 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 54 Imported by: 0

Documentation

Overview

`satelle agent` selects the headless agent CLI the quality-management spine shells out to for isolated reviews/summaries (the install-time choice, sty_b6973a7b). The selection persists in the global config (~/.satelle/config.toml [agent] cli) so every repo's reviewer resolves the same agent; the reviewer/summariser never name a binary directly.

`satelle agent validate` (sty_93eec36d) is the store-backed check of this repo's .satelle/agents.toml + workflow agent= bindings — the same authority init and story engagement use. It is deliberate that there is no top-level `satelle validate`: each noun validates its own.

`satelle skill|workflow|principle create` is satelle's gated upsert path for authored objects: it writes the markdown file THROUGH the object's DETERMINISTIC structure check (internal/structure), refusing to persist a non-conforming artifact — the same discipline `satelle story create` applies to work items. The check is code, not an LLM rubric: harness-independent and never flaky.

`satelle help` renders the embedded help topics to the terminal — the create-story path and the reviewer checks (sty_82c456a0). With no argument it lists the topics; with a topic name it prints that guide. The same topics back the web `/help` page (internal/help is the shared source). This is distinct from cobra's per-command `--help`: it documents the process, not the flags.

`satelle hook` carries the Claude Code hook handlers. Currently one: `satelle hook context` — the SessionStart always-context injector (sty_e3922598).

At session start it fetches every `principles:session`-flagged authored doc and injects their bodies as session context, followed by the standing "pull the rest on demand" instruction. This keeps the minimal SYSTEM residency set in front of the agent without auto-injecting an unbounded list — the bodies are bounded by a byte ceiling, and an overflow is reported on stderr (never silently dropped). It FAILS OPEN: an unconfigured repo or any read error injects nothing and never blocks the session.

Residency taxonomy (sty_1278fdd9 / satelle-residency): ONE classifier —

system   = carries the principles:session tag → injected every session
ondemand = no marker (default) → pulled only when a skill/workflow references it

Frontmatter scope: on principles is NOT an injection axis (removed; inert if reintroduced). Ownership (embedded_sha) is orthogonal to residency.

`satelle migrate` — one deterministic verb converging a repo to the current substrate-planes structure (sty_a3915840 / epic:substrate-planes). Composes existing mechanism: home-keyed runtime relocation, legacy residue removal, unedited-seed prune, gitignore managed-block convergence, then deployment validation. Dry-run by default; --yes applies.

`satelle runtime` — inspect and migrate the home-keyed runtime plane (sty_4660bbe1 / epic:substrate-planes). Runtime state (satelle.db, logs, backups, stories cache) lives under ~/.satelle/<repo-key>/; authored substrate stays under <repo>/.satelle. Migration is EXPLICIT — open never moves a DB.

`satelle substrate` — effective process view and virtual-defaults tooling (sty_29e5a9a5 / epic:substrate-planes). Defaults resolve from the binary; on-disk files are overrides. list --effective shows provenance; edit materializes a default for day-one editing; prune removes unedited seeds.

`satelle update` is an inline self-updater (like `claude update`): it resolves the latest GitHub release, and if newer than the installed binary, downloads the platform asset, sha256-verifies it, and atomically replaces the installed binary — the SAME asset/checksum/install-dir scheme as scripts/install.sh, so the two never drift. If the background service is running it is restarted onto the new binary.

Per-noun validation: `satelle workflow|skill|principle|task validate [name]`. "validate" is a SEMANTIC, kind-specific check — a valid workflow PROCESS, a valid skill contract — run DETERMINISTICALLY (code, not an LLM rubric) over the on-disk files, reporting pass/fail and exiting non-zero on any failure. It is distinct from OKF conformance, which `satelle reindex` owns and self-heals. There is no generic top-level `satelle validate`: each noun validates its own.

`satelle workflow list` surfaces the workflows that apply to a story category, in selection-priority order — the list satelle offers an agent starting a story. The head is the active/default workflow the engine enforces; a PROJECT (repo) workflow overrides the embedded SYSTEM default, and a category-specific workflow overrides a wildcard (applies_to ["*"]). Read-only.

`satelle workspace` manages the connected-repo registry the /workspace view aggregates (build order step 6). The registry lives in the global config (~/.satelle/config.toml [workspace] repos); per-repo databases stay the source of truth. `workspace add` also seeds the push-fed serve mirror, bootstrapping [server] endpoint into satelle.local.toml when a local serve is reachable (sty_805bee9c / sty_0122610a / epic:serve-adoption).

Mirror hygiene (epic:mirror-hygiene / sty_5aa08259 / sty_eb61be02):

  • SATELLE_SERVER_ENDPOINT=none disables discovery and push (hermetic tests).
  • Auto-bootstrap only adopts a serve whose X-Satelle-Instance matches this SATELLE_HOME — foreign :8787 answers are not seeded.
  • workspace remove purges the mirror partition; partitions / prune manage orphans (test pollution).

embedded_provenance.go — file-local provenance for embedded-owned substrate (sty_304ee454). init/rebase STAMP every embedded default they materialise with a frontmatter `embedded_sha:` line = sha256 of the embedded body as shipped. On re-init the stamp lets us CONVERGE an UNEDITED stale copy to the current binary while never clobbering an operator edit:

  • no stamp -> operator-authored -> UNTOUCHED
  • stamp, strip-hash == stamp: stamp == sha(current embedded) -> unchanged (no-op) stamp != sha(current embedded) -> binary advanced -> OVERWRITE + re-stamp
  • stamp, strip-hash != stamp -> operator EDITED -> back up, surface, keep

The stamp is the ONLY line added on write, and applyEmbeddedStamp / stripEmbeddedStamp are exact byte inverses, so re-stamping an unedited file never registers as an edit (AC6).

init_analysis.go — substrate analysis phase of `satelle init` (init-substrate-analysis).

After mechanical seed/heal, init reports residual defects so the LOCAL agent can act: placement/residency/tag-axis problems (fatal), an unedited scaffold constitution (advisory), and missing scaffold-seeded config keys (advisory). Each defect names file + defect + fix channel. Repo-agnostic: driven by EmbeddedDefaults, sessionTag, whitelist, scaffold markers — no this-repo ids.

Repo-local satelle binary (sty_fe3ee313): a repo may pin its own satelle under .satelle/satelle (installed by `satelle update --local`). When that pin is present, it is the binary that runs for the repo — the globally-invoked satelle re-execs the local one at startup. This keeps the product repo-agnostic (satelle-repo-agnostic): the pin is an installed RELEASE asset, never a source build, and nothing about any one repo is baked into the binary.

placement.go — deterministic substrate placement validator (epic:substrate-convergence order:6).

Guards four post-order-1–5 invariants so placement cannot silently drift:

  1. embedded-owned on-disk copies that still match the embedded body carry embedded_sha (order:1 provenance)
  2. the only legal principles:* tag is principles:session (order:3 residency)
  3. no inert scope: key on principles (order:3 removed that axis)
  4. resident set + constitution stay under alwaysContextCeiling (order:4 diet)

Anchored under `satelle principle validate` (whole-set, nameFilter empty) — same pattern as workflow consistency. Complements the semantic satelle-substrate-audit skill; this package is code-only, repo-agnostic (no this-repo story ids; driven by EmbeddedDefaults, sessionTag, ceiling).

principle_heal.go — deterministic principle frontmatter migrations on init (sty_cc8ce91c). Removes inert scope: and rewrites principles:always → principles:session so binary-introduced drift does not block the stamp.

Package cli wires the satelle command-line interface.

Subcommands self-register via init() calling register(), so adding a new verb is one new file under internal/cli/ — no edits to a central switch. Ported from satellites' internal/cli/root.go, stripped of the engagement ticker (the local OSS tier has no leased session to heartbeat).

runtime_liveness.go — refuse relocating a live runtime (sty_5308eb60).

migrate / runtime migrate take a VACUUM INTO snapshot of the legacy DB and then remove it as residue. Without a liveness guard, every write the working session commits AFTER the snapshot is stranded (deleted inode / removed file) while new processes read the home-keyed copy. This package is pure mechanism: detect live holders, refuse (or warn under --allow-live).

substrate_backup.go — shared pre-mutation backup for authored substrate (sty_873a5380). Local floor always under the runtime plane's backups/ tree (~/.satelle/<repo-key>/backups/ when home-keyed — sty_4660bbe1); optional personal hosted push when configured+authenticated; advisory (never a gate) when no hosted channel and the operator has not opted local-only.

Snapshot build + POST helpers for the push-fed local UI mirror (sty_1dde0d47 / sty_805bee9c). The operator verb is `satelle workspace add` (register + seed); mutating verbs drain via uiDrain. The retired `ui push` spelling points at workspace add (retiredNames).

wikilink.go — deterministic [[wikilink]] resolution for authored substrate.

The pull channel depends on [[name]] references; until this check existed, dangling links silently killed on-demand discoverability. Every wikilink in substrate (principles, skills, workflows, documents, constitution) must resolve to a known artifact name across kinds (disk + embedded defaults).

Repo-agnostic: catalog is built from dataDir + EmbeddedDefaults only. Bash `[[` tests are excluded (target must start with an alphanumeric — character classes like [[:space:]] do not match).

Index

Constants

View Source
const EnvServerEndpoint = "SATELLE_SERVER_ENDPOINT"

EnvServerEndpoint is the CLI override for [server] endpoint discovery and push (sty_5aa08259). Values:

unset          — use config / auto-bootstrap probe as usual
URL            — use that base URL; no default-port probe
none|off|-|""  — disable discovery AND push (hermetic tests set this)
View Source
const HeaderSatelleInstance = "X-Satelle-Instance"

HeaderSatelleInstance is the serve /healthz response header carrying the home-derived instance id (sty_5aa08259).

Variables

View Source
var ErrWorkstatePullConflict = errors.New("workstate pull conflict")

ErrWorkstatePullConflict is returned when local and hosted both have data for an opted-in area and --force was not set. Nothing is written before this error.

View Source
var WorkstateAreas = []string{"stories", "executions", "ledger"}

WorkstateAreas are the sync areas that form the work-state kind. A shared scope on any of these only means "eligible to leave the machine" — destination remains the personal workspace.

Functions

func Execute

func Execute() error

Execute runs the root command and, on an unknown subcommand, follows the bare cobra error with the command's usage so a mistyped command guides the user instead of dead-ending. Removed spellings fail closed naming their replacement. Returns the command's error so the caller sets a non-zero exit.

func NewRootCmd

func NewRootCmd() *cobra.Command

NewRootCmd returns the root cobra command with every registered subcommand attached.

Types

type BackupKind added in v0.0.230

type BackupKind string

BackupKind names the backup sub-tree (diverged / pre-mutation / restore / …). Layout: <runtimeDir>/backups/<kind>/<relPath> — deterministic, clock-free for single-file kinds so re-runs overwrite the same slot (idempotent).

const (
	BackupKindDiverged    BackupKind = "diverged"
	BackupKindPreMutation BackupKind = "pre-mutation"
	BackupKindRestore     BackupKind = "restore"
)

type BackupOpts added in v0.0.230

type BackupOpts struct {
	// LocalOnly suppresses the "enable online backup" advisory (operator
	// opted out via [backup] local_only = true).
	LocalOnly bool
	// HostedServer/Project when non-empty attempt a personal hosted push of
	// the pre-image. Failures degrade to local-only with a non-fatal notice.
	HostedServer  string
	HostedProject string
	// Now, if non-zero, stamps time-based roots (restore batch). Zero uses
	// time.Now() when a timestamped root is needed.
	Now time.Time
	// HostedPush is an optional override for tests (nil → real hosted client).
	HostedPush func(ctx context.Context, relPath string, body []byte) (dest string, err error)
	// BackupsDir is the parent of the backups/ tree (the runtime plane —
	// sty_4660bbe1). When empty, backupExistingFile uses its dataDir argument
	// as that parent (tests / single-tree fixtures).
	BackupsDir string
}

BackupOpts tunes the online/local policy for one backup call.

func ResolveBackupOpts added in v0.0.230

func ResolveBackupOpts(cfg config.Config) BackupOpts

ResolveBackupOpts reads the backup policy from cfg (and defaults). Safe with a zero config. Hosted documents push is OPT-IN via [backup] hosted = true (sty_84f14ace); when false, HostedServer/HostedProject stay empty so the existing server+project gate on the push path stays quiet. Hosted server URL uses global→repo precedence (config.ResolveHostedServer) when opted in.

type BackupResult added in v0.0.230

type BackupResult struct {
	LocalPath string // absolute path under dataDir/backups/…
	// Notice is a single line for command output (hosted destination, degrade
	// notice, or the online-channel advisory). Empty when nothing to print.
	Notice string
}

BackupResult describes where a pre-mutation copy landed.

type ScaffoldFinding added in v0.0.225

type ScaffoldFinding struct {
	Path   string // repo-relative path of the drifted artifact
	Kind   string // missing | content | command
	Detail string
}

ScaffoldFinding is one deployed-vs-canonical harness scaffold mismatch (sty_ac25b787). Paths are repo-relative; no absolute machine paths.

func DetectScaffoldDrift added in v0.0.225

func DetectScaffoldDrift(repoRoot string) []ScaffoldFinding

DetectScaffoldDrift compares deployed harness hook configs and .satelle/hooks scripts against this binary's canonical wrappers. Empty when no harness scaffolding is deployed or everything matches. Repo-agnostic: only well-known relative paths (settings + script names) are examined.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL