hygiene

package
v1.2.5 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package hygiene is the one place that answers "is this diff clean", for the accept gate, for the merge lane and for a hand.

SPEC-TOOLWORK.md, Hygiene. Four mechanical questions, none of which reads prose and none of which needs a model:

identity     every commit in the range is the pool's own, and none is a merge
out-of-path  every changed path matches one of the card's declared globs
stray-file   nothing was added that does not belong in a repository
secret       no added line has the SHAPE of a key

One implementation and three callers -- `nova-pulse accept` at harvest, `nova-merge batch` on every member, and `nova-check hygiene` for a person before they ask for a read -- so the lane and the harvest cannot disagree about what clean means. A second implementation is a second definition, and the day they drift is the day a card passes one and fails the other with nobody able to say which is right.

What it does not do: it never opens RESULT.md or any other prose the worker wrote, it never prints a matched secret, and it never decides anything. It returns findings; the caller decides what a finding costs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InstructionKind

func InstructionKind(name string) (string, bool)

InstructionKind is the instruction kind of a declared work kind, the column of the one list (docs/SPEC-ISA.md). ok is false when name is not declared or the row names no instruction kind.

func KindDeclared

func KindDeclared(name string) bool

KindDeclared says whether the KIND: line names a shape of work the tool declares. There is no default kind, and a kind not present in the table is refused.

func KindGated

func KindGated(name string) bool

KindGated reports the gated column of the one kinds list (docs/SPEC-ISA.md keeps that column on the same list). A kind the list does not declare is gated: TEST: none is not a declaration for it.

func Kinds

func Kinds() []string

Kinds is the card kinds this toolchain declares, in the spec's order. A caller that refuses an unknown kind prints this, because a refusal a reader cannot act on is a refusal that sends them to the source.

func MatchGlob

func MatchGlob(glob, p string) bool

MatchGlob answers whether a repo-relative path matches one PATHS glob. `*` stays inside one segment, as path.Match has it; `**` spans any number of segments, which path.Match does not do at all and which is why this is written out rather than delegated.

The S7 wall (SPEC-SWARM the harness wall) uses this same matcher: a card-scope read is admitted when it matches a declared write PATHS glob or a dispatcher-approved contextual-read glob, and a second matcher would be a second definition.

func ValidatePaths

func ValidatePaths(paths []string) error

ValidatePaths is the PATHS: line's own rule. It is checked at `cut`, before a card is admitted, and again here before the line is used to judge a diff: a bound that is validated only at the point it is written is a bound that any later edit removes.

No `..`, because a glob that climbs out of the repository bounds nothing. No absolute path, for the same reason and because a card's paths are repo-relative by definition. No glob that matches every file there is, because a card whose declared paths are "everything" has declared nothing -- the check would run and always pass, which is worse than not running, because the row would say it ran.

That last rule is not a list of spellings. `**` and `**/` were refused by name, and `**/*`, `*/**` and a bare `*` walked straight past them and matched everything just the same. What bounds a glob is a LITERAL character somewhere in it that a path has to carry, so that is what is asked for: one segment holding something that is not a wildcard. `sign/**`, `*.go` and `**/*.go` all clear it; `**/*` and `*/**` do not.

Types

type Finding

type Finding struct {
	Token string // identity | out-of-path | stray-file | secret
	At    string // <sha12>, <path>, or <path>:<line>
	Why   string
}

Finding is one thing wrong, in the form the gate's REJECT line prints: a token, and where. Why is one line for a person and never carries matched secret text.

func Check

func Check(ctx context.Context, o Options) ([]Finding, error)

Check runs the four checks over base..head and returns everything wrong, in a stable order. An error is a could-not-run (a bad ref, a repo that is not a working copy) and is never a finding: a check that could not run has found nothing, and reporting it as clean is the one answer that must not be possible.

func (Finding) String

func (f Finding) String() string

type Identity

type Identity struct {
	Name  string
	Email string
}

Identity is one line at a keyboard: the name and email a commit in this range must carry, as the pool's identity.tsv (or the lane's identities.tsv) spells it.

type Options

type Options struct {
	Repo string
	Base string
	Head string

	// Paths is the card's PATHS: globs. ABSENT (nil or empty) means the diff is not
	// bounded -- a friend's batch member has no card and no declared paths -- and
	// out-of-path is skipped and said to be skipped (`paths=-`), never silently
	// passed.
	Paths []string

	// Identities is a set: at harvest the pool's one row, at batch every friend who
	// commits to this repository. An empty set is a refusal, not a pass: a range
	// checked against nobody would admit anybody.
	Identities []Identity

	// Kind is the card's KIND:, used only to honour an allowlisted stray exception
	// that names the kind it is for. Empty means no exception applies.
	Kind string
}

Options is one call. The spec's signature is Check(repo, base, head, paths, identity); it is a struct here because two of the five are sets whose absence means something specific, and a positional nil says neither which nor why.

Jump to

Keyboard shortcuts

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