cardtree

package
v1.2.11 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 17 Imported by: 0

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

View Source
const (
	OK      = "ok"
	Broken  = "broken"
	NotDone = "not-done"
	Skipped = "skipped"
)

The verdict words of a step line.

View Source
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).

View Source
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

View Source
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.

View Source
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`.

View Source
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

func AmbiguousCommit(prefix, branch string) error

AmbiguousCommit is a prefix of two commits of the branch, or one git calls ambiguous.

func Guide

func Guide(t Tree) string

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

func RefusedCommand(argv []string) string

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

func Remainder(card, id, from, land string) (string, error)

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

func RemainderID(id, from string) string

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

func ScrubEnv(env []string) []string

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

func UnknownCommit(prefix, branch string) error

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

type Edit struct {
	RE   *regexp.Regexp
	Repl string
}

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

func ParseRegex(program string) ([]Edit, error)

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

type Finding struct {
	Check   string
	Line    int
	Excerpt string
}

Finding is one defect of a tree: the lint's rule token, the 1-based line, the excerpt.

func Lint

func Lint(card string) []Finding

Lint is every defect of a tree card, in card order; nothing for a flat card. The top-level numbering (1, 2, 3) is the card lint's own `steps-numbered`; this holds the dotted numbers.

type Post

type Post struct {
	Line int
	Raw  string
	Kind string
	Path string
	Sum  string
	Argv []string
}

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

type Result struct {
	Num     string
	Verdict string
	Sha     string
	Words   string
}

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

func Land(t Tree, v map[string]Result) (failed *Result, land string)

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

func RunScript(dir string, s Step, sys Sys) Result

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.

func Walk

func Walk(t Tree, do func(Step) Result) []Result

Walk is the tree walked depth first: do runs each work step the walk visits, and the walk stops at the first step that is not ok, since the steps after it build on it.

func (Result) Line

func (r Result) Line() string

Line is the step's verdict line as the result carries it.

type ShaResolve

type ShaResolve func(prefix string) (sha string, err error)

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.

func (Step) Script

func (s Step) Script() bool

Script says the step is a script step: a program the member runs, no model.

func (Step) Work

func (s Step) Work() bool

Work says the step is a work step: it carries its own commit line.

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.

func OSSys

func OSSys(work string, w Wall) Sys

OSSys is the machine's Sys: the toolchain builds outside the wall, and the card's code and git's commit run in w, one wall per command, with no shell.

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

func Parse(card string) Tree

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

func (t Tree) AllScript() bool

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) HasScript

func (t Tree) HasScript() bool

HasScript says some work step the walk visits is a script step.

func (Tree) IsTree

func (t Tree) IsTree() bool

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.

func (Tree) Step

func (t Tree) Step(n string) (Step, bool)

Step is the step numbered n, and whether there is one.

func (Tree) Work

func (t Tree) Work() []Step

Work is the work steps the walk visits, in card order (depth first), from the From: step on when the card names one.

type Wall

type Wall struct {
	Bin  string
	Read []string
	Tmp  string
}

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) Argv

func (w Wall) Argv(dir string, argv []string) []string

Argv is the wall's argv around one command run in the checkout dir.

func (Wall) Env

func (w Wall) Env(env []string) []string

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.

Jump to

Keyboard shortcuts

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