Documentation
¶
Overview ¶
Package cardtree is a card as a tree of steps (docs/SPEC-SPRINT.md, "A card is a tree of steps"; nova-tools#5174 rule 7): the grammar of numbered step blocks, the lint of a tree, the script step the member runs with no model, the verdict per step, and the remainder a failed step leaves. The owner, 2026-10-02: "any card can be a tree"; "a batch card is just nomenclature". A card with no tree in it is a flat card, and nothing here changes it.
Index ¶
- Constants
- Variables
- func AmbiguousCommit(prefix, branch string) error
- func Guide(t Tree) string
- func ParseVerdicts(body string, resolve ShaResolve) map[string]Result
- func RefusedCommand(argv []string) string
- func Remainder(card, id, from, land string) (string, error)
- func RemainderID(id, from string) string
- func ScrubEnv(env []string) []string
- func UnknownCommit(prefix, branch string) error
- type CommitMiss
- type Edit
- type Finding
- type Post
- type Result
- type ShaResolve
- type Step
- type Sys
- type Tree
- type Wall
Constants ¶
const ( OK = "ok" Broken = "broken" NotDone = "not-done" Skipped = "skipped" )
The verdict words of a step line.
const ( CheckNested = "steps-nested" CheckStep = "tree-step" CheckScript = "script-step" )
The rule tokens a tree's findings carry, and what each wants (the lint prints the remedy).
const StepBudget = 10 * time.Minute
StepBudget bounds one program, one POST command or one git of a script step; the card's own deadline bounds the whole run.
Variables ¶
var (
Langs = []string{"regex", "go", "lisp"}
)
The languages a script step may be written in (docs/SPEC-SPRINT.md, a card is a tree of steps: "preference: lisp, or golang obv.", a regex at simplest), and the interpreters refused by name, as a SCRIPT: language and as an exit0 command's first word.
var Remedies = map[string]string{ CheckNested: "a dotted step `STEP <n>.<k>.` sits under its parent `STEP <n>.`, and the children of one parent are numbered 1, 2, 3 with no gap and no repeat", CheckStep: "a work step (one with COMMIT:) carries its own PATHS:, COMMIT: and VERDICT: lines, every glob of its PATHS: is a relative path inside the checkout and one of the card's PATHS: or NEW: globs, a step with PATHS:, VERDICT:, SCRIPT: or POST: and no COMMIT: is missing its COMMIT:, and From: STEP <n> names a step of the card", CheckScript: "a script step says `SCRIPT: regex|go|lisp` (never bash or python), carries its program in one fenced block under it, and at least one `POST: sha256 <path> <64 hex>` or `POST: exit0 <command>` line the gate asserts (a path inside the checkout; a command that is no interpreter: never bash, sh, zsh, python, python3, perl or env), and every work step of its card is a script step; a regex program is lines of `s/<re>/<replacement>/` in Go regexp syntax", }
Remedies is the remedy of each rule token, for `nova-swarm lint --rules`.
var ( // StepRE is a STEP line: `STEP 3.` or a dotted child `STEP 3.1.`. StepRE = regexp.MustCompile(`^STEP[ \t]+([0-9]+(?:\.[0-9]+)*)`) )
Functions ¶
func AmbiguousCommit ¶
AmbiguousCommit is a prefix of two commits of the branch, or one git calls ambiguous.
func Guide ¶
Guide is what a tree card's child is told beside its brief (member.CardText): walk the work steps depth first, one commit per step, a step line each in the pull request body, stop at the first that is not ok. A card with a script step never reaches a child: every work step of it is a script step (the lint), which the executor runs.
func ParseVerdicts ¶
func ParseVerdicts(body string, resolve ShaResolve) map[string]Result
ParseVerdicts reads every step line of a result's body, by step number; the first line for a step wins. A line whose commit is neither `-` nor 7 to 40 hex is a defect: the step is not-done, its words say why, so no word is ever pushed as a head. A hex commit is a prefix, resolved by resolve to the one full sha of the branch; a full sha is checked the same way. nil resolve accepts a 40-hex sha as itself and refuses a shorter one as unknown.
func RefusedCommand ¶
RefusedCommand says why an exit0 command is refused, "" when it is not: its first word is an interpreter (or env, which runs one), the "never bash or python" rule a POST line could otherwise walk round.
func Remainder ¶
Remainder is the card a failed step leaves (docs/SPEC-SPRINT.md, a card is a tree of steps): the brief as it is, staged at land, the full commit steps 1..n-1 landed at, with `From: STEP <n>` (the walk starts there) and `Needs: <id>` (it is dealt after the card it continues). In the header: line 1's `sha=` becomes land's first twelve, `BASE: <ref>[@<sha>]` becomes `BASE: <ref>@<land>` and `base-sha:` becomes land (a card with neither gains a `base-sha:` line); an existing From: line is replaced, an existing Needs: line extended.
func RemainderID ¶
RemainderID is the id of the card the step n of card id leaves: `<id>-r<n>`, a dotted step's dots as dashes (`c1-r3-2`), so the id is one the sprint takes (sprint.ValidID).
func ScrubEnv ¶
ScrubEnv is env without a variable whose name carries a credential word or whose value holds a URL's `user:password@`, and without HOME, GIT_CONFIG_GLOBAL and GIT_CONFIG_NOSYSTEM, which the step's wall sets for itself. It is a denylist: run by native, the executor's environment is already the child's allowlist (keepNativeEnv), and this is the second filter; run directly, `nova-swarm step` passes the caller's other variables through.
func UnknownCommit ¶
UnknownCommit is a prefix of no commit of the branch.
Types ¶
type CommitMiss ¶
type CommitMiss struct {
Kind, Prefix, Branch string
}
CommitMiss is a step commit that is 7 to 40 hex but not one commit of the branch. Kind is "ambiguous" or "unknown".
func (*CommitMiss) Error ¶
func (e *CommitMiss) Error() string
type Edit ¶
Edit is one line of a regex program: every match of RE in a file becomes Repl ($1 expands as in regexp.Expand).
func ParseRegex ¶
ParseRegex reads a regex program: one `s<d><re><d><replacement><d>` per non-blank line, any delimiter d, Go regexp syntax; a line beginning `#` is a comment.
type Finding ¶
Finding is one defect of a tree: the lint's rule token, the 1-based line, the excerpt.
type Post ¶
Post is one post-condition line of a script step: `POST: sha256 <path> <hex>` (the file's hash after the program) or `POST: exit0 <argv>` (a command run in the checkout, no shell, that must exit 0). Kind is "" for a line that is neither.
type Result ¶
Result is one work step's verdict: `step <n>: <verdict> <sha|-> <words>`, one line per work step in the result's body, in walk order (docs/SPEC-CARD-CONTRACT.md section 3, the verdict per step). Sha is the step's own commit, "" when it made none.
func Land ¶
Land is where a tree card's result lands (docs/SPEC-SPRINT.md, a card is a tree of steps: the coordinator's failed-step rule of 2026-10-02): the first work step whose verdict is not ok (a step with no line is not-done), and the commit of the last ok step before it that made one. failed is nil when every step is ok; land is "" when no step before the failed one committed anything.
func RunScript ¶
RunScript runs one script step in the checkout dir with no model: the program, then every POST line, then the step's commit (docs/SPEC-SPRINT.md, a card is a tree of steps). A program or a POST that fails is broken and commits nothing; a program that changed nothing while its POST holds is ok with no commit. A path that is not local to the checkout, and a POST command an interpreter would run, are refused here as the lint refuses them.
type ShaResolve ¶
ShaResolve turns a 7 to 40 hex step commit into the one full sha of the branch the result names (docs/SPEC-SPRINT.md, the verdict per step). The member supplies it; this package does not run git. An ambiguous prefix and an unknown one come back as *CommitMiss.
type Step ¶
type Step struct {
Num string // "2", "3.1"
Line int // the STEP line, 1-based
Text string // the STEP line itself
Paths []string
Commit string
Verdict string
Lang string // SCRIPT:'s value, lower case; "" for a model step
Fence string // the program fence's info string, lower case
Fenced bool // a fenced block was found in the body
Program string
Post []Post
// contains filtered or unexported fields
}
Step is one `STEP <n>.` block of a card: its line and every line under it to the next STEP line. A step carrying COMMIT: is a work step (one commit, one verdict); a work step carrying SCRIPT: is a script step, which the member runs and no model does.
type Sys ¶
type Sys struct {
Build func(dir string, argv ...string) error
Run func(dir string, argv ...string) error
Commit func(dir string, paths []string, message string) (sha string, err error)
Work string
}
Sys is what a script step needs of the machine (docs/SPEC-SPRINT.md, a card is a tree of steps): Build runs the toolchain over a program's source, never the card's code; Run runs the card's code (a built program, sbcl, an exit0 command) in the step's own wall; Commit stages the step's paths and commits them, in that wall too, and says the sha ("" when nothing changed). Work is where the programs are written and built. The executor's is OSSys; a test's is its own.
type Tree ¶
type Tree struct {
Steps []Step
Paths []string
From string // the header's `From: STEP <n>`: the walk starts there; "" when none
FromLine int
}
Tree is a card read as a tree: every step in card order (which is the walk's order, depth first), the header's PATHS: and NEW: globs, and its From: step.
func Parse ¶
Parse reads a card's steps and the header lines a tree needs. It never fails: what it cannot read, Lint names.
func (Tree) AllScript ¶
AllScript says every work step the walk visits is a script step: the card runs with no model at all (native runs the executor in place of the harness).
func (Tree) IsTree ¶
IsTree says the card is a tree: a dotted step, a step with a tree field (COMMIT:, PATHS:, VERDICT:, SCRIPT:, POST:) or a From: line. A flat card has none, and every rule of today applies to it unchanged.
type Wall ¶
Wall is a script step's own wall (docs/SPEC-SPRINT.md, a card is a tree of steps), tighter than a child's: the network denied (`--net-deny`, which the wall refuses where it cannot enforce it), no credential in the environment (ScrubEnv; the step needs no model), and the write set the checkout and a private temp only. Bin is the wall binary; "" runs with no wall, which only an explicit --no-wall asks for. Read is the read flags the step needs (the built programs, the toolchain, the checkout's borrowed objects): `--read <dir>` and `--read-noexec <dir>` pairs. Tmp is the private temp; HOME is <Tmp>/home.
func (Wall) Env ¶
Env is the environment of a command in the step's wall: the caller's, scrubbed of every credential (ScrubEnv), HOME the private one, git kept off any configuration but the checkout's own, Go's and the shell's temps the private one (a caller's GOTMPDIR or TMPDIR, a CI runner's own directory, is outside the wall's write set), Go's build cache a private one in the temp (the bench's shared cache is neither read nor written by a step, so no card's program can poison it), modules read from the module cache the wall reads and never fetched.