Saphan StudioDocs
Reference/Command reference

saphan checks

The track's deterministic-task catalog (build/test/lint/importcheck/plugin-compile) as proc-runs, never an LLM turn

saphan checks

The track's deterministic-task catalog (build/test/lint/importcheck/plugin-compile) as proc-runs, never an LLM turn

saphan checks

Subcommands

SubcommandWhat it does
saphan checks channel-lintLint a worktree's channel files with the SAME parser the bus uses ($0 deterministic; rider M2)
saphan checks container-contradictionsRefuse container runs that lacked a fresh exact-image docker-oci probe at start time
saphan checks declarePrint the declaration line: ready for the deterministic checks — no LLM turn spent running them
saphan checks listPrint the catalog as literal saphan run --backend proc commands (shown, not merely described)
saphan checks ui-assetsAssert the embedded UI bundle's screen-key parity with an exit code, wherever the startup notice is quiet
saphan checks vendor-attributionRefuse a branch whose commits carry a vendor Co-authored-by trailer (zero AI attribution)

saphan checks channel-lint

Lint a worktree's channel files with the SAME parser the bus uses ($0 deterministic; rider M2)

saphan checks channel-lint [flags]

Parse _MASTER_ORDER.md, _EXEC_STATUS.md, and _REVIEW_STATUS.md (whichever are present in the worktree) with the EXACT SAME domain.ParseOrder / domain.ParseStatus / domain.ParseReviewStatus functions bus/reconcile.go calls — never a second, divergent grammar. A file absent is not a finding (not every worktree carries every channel file, and a worktree carrying only _MASTER_ORDER.md is a leg that has not started); a worktree carrying NONE of the three files is a different claim — nothing to evaluate, a named finding, exit 2. A file present but malformed under the bus's own grammar is a named finding, exit 2 (STOP), and so is a channel that PARSES but carries a shape the bus does not read as its author intended: a "- state:" token outside the vocabulary bus/reconcile.go itself reads, a missing/empty state, a "#" heading that de-records the canonical keys beneath it, or two channel files in one worktree naming two different streams. Run this as your own last act before emitting CLOSE-OK, or as the master's check before accepting a STOP-2 return.

Options

OptionTypeDefaultDescription
--worktreestringunsetabsolute path of the worktree whose channel files to lint (required)

saphan checks container-contradictions

Refuse container runs that lacked a fresh exact-image docker-oci probe at start time

saphan checks container-contradictions

saphan checks declare

Print the declaration line: ready for the deterministic checks — no LLM turn spent running them

saphan checks declare [flags]

Options

OptionTypeDefaultDescription
--actorstringunsetmandate holder's id (required)
--classstringArray[]catalog class to declare ready (repeatable; default: the whole catalog)
--streamstringunsetstream slug declaring readiness (required)

saphan checks list

Print the catalog as literal saphan run --backend proc commands (shown, not merely described)

saphan checks list [flags]

Options

OptionTypeDefaultDescription
--actorstringunsetmandate holder's id for the composed runs (required)
--streamstringunsetstream slug the composed runs would belong to (required)
--workdirstringunsetthe track's repo root the checks run against (required)

saphan checks ui-assets

Assert the embedded UI bundle's screen-key parity with an exit code, wherever the startup notice is quiet

saphan checks ui-assets

Load the embedded UI bundle and report its screen-key verdict.

The startup notice about unresolved screen keys is heard only by the verbs that render or serve those screens (console, serve, server, serverd). This verb is where the same finding stays for everyone else: it exits 2 while any screen key resolves to no string in both catalogs, and names each one, so a gate, a CI step or an operator can ask the question directly instead of reading it off the top of an unrelated command's stderr.

It also prints which verbs are in the notice's audience — derived from the assembled command tree, never a list typed beside it.

saphan checks vendor-attribution

Refuse a branch whose commits carry a vendor Co-authored-by trailer (zero AI attribution)

saphan checks vendor-attribution [flags]

Scan every commit in merge-base(base, branch)..branch for Co-authored-by trailers whose email does not belong to a known human commit author in this repo. A vendor co-author (Claude, Qwen-Coder, etc.) is identified NOT by a hard-coded list of vendor names — which rots the moment a new backend is admitted — but by a structural property of the DATA: the set of commit author emails the repo already carries are the known humans (the fleet rule "Commit author Marcin Marzec" means every commit author is a human), so a co-author whose email is absent from that set is a vendor. This survives the false positives a name-matching approach produces: "qwen" in a commit BODY is domain vocabulary, not attribution, and this check never reads the body — only the Co-authored-by trailer, a structured field.

The remediation names the act that actually works: git commit --amend is refused to legs by the permission layer, so the owner must strip the trailer before the gate.

Options

OptionTypeDefaultDescription
--basestringunsetthe base ref to merge against, e.g. origin/develop (required)
--branchstringHEADthe branch ref to check (default: HEAD)
--repostringunsetthe git repo path to check (required)

On this page