verify

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package verify discovers the project-wide build and test entrypoints that form the session-end machine verification floor, runs one of them, and reads the failing test names out of what it printed.

It sits here, in its own package, on purpose, and the reason is a law about laws: A LAW ABOUT A PROJECT'S OWN VERIFICATION THAT ONLY ONE CALLER CAN REACH IS A LAW EVERY OTHER CALLER SILENTLY DOES WITHOUT. When this code was unexported inside a package the plain `codeaf do` path could not import, the repository was never photographed, two readings of it were never compared, and patches shipped that deleted attributes the repository already had while their own narrow tests stayed green (docs/design/gate/SETTLEMENT.md §4).

Nothing here knows what language the workspace is in, and nothing here is a gate. It discovers, it runs, it reads, and it subtracts; what a caller does with a new red name is the caller's business.

Index

Constants

View Source
const (
	// ShapeUse is the answer for every arrangement this reader cannot name. It
	// is the honest one: the project mentions the name here and this program has
	// nothing structural to say about how.
	ShapeUse = "use"
	// ShapeCall is the name followed by an argument list.
	ShapeCall = "call"
	// ShapeSubscript is the name indexed, and ShapeSubscriptAssign is the name
	// indexed on the LEFT of an assignment — the one arrangement igel s12 broke
	// and the reason the two are told apart at all.
	ShapeSubscript       = "subscript"
	ShapeSubscriptAssign = "subscript-assign"
	// ShapeAttribute is the name with a member reached off it, carrying the
	// member: `attribute .get` and `attribute .results_path` are different facts
	// about what a caller expects to find behind a name.
	ShapeAttribute = "attribute "
	// ShapeIterate is the name iterated over, and ShapeInstantiate is the name
	// constructed with a language's own keyword for it.
	ShapeIterate     = "iterate"
	ShapeInstantiate = "instantiate"
)
View Source
const ReplacementsNamed = 4

ReplacementsNamed bounds how many heirs one replacement records.

A journal row is read to learn WHAT SHAPE the replacement had — whether one stub became one check or one stub became nine — and four settles that as well as forty. It is the same reasoning store.VerificationSample spells for a roster sample, at the size internal/revision spells for a list of observables.

View Source
const ScopeWhole = "whole"

ScopeWhole is what a reading of everything the entrypoint covers calls itself. It is a word rather than an empty string because a scope that says nothing is indistinguishable from a reading taken before scopes existed, and those are the two things the comparison rule most needs to tell apart.

View Source
const ShortestUsefulReading = time.Minute

ShortestUsefulReading is the floor under that share, and it is the refusal this file exists to state as a law: A RUN WHOSE WALL CANNOT AFFORD A REAL READING TAKES NO READING AT ALL, rather than spending an eighth of its life on a command that will be killed before it says anything.

One minute is derived from the fastest whole suite measured in the sweep this work comes from — igel's two passing project tests, "2 passed in 27.86s" — doubled to leave room for an interpreter, an import graph and a compile. A budget under that cannot hold even the cheapest observed project suite, so a reading taken with it would time out, name nothing, and cost an eighth of a wall for a Result that says nothing at all.

View Source
const WallShare = 8

WallShare is the denominator of the leaf's own wall that ONE reading of the project's own verification may spend.

It is a share and not a duration because the thing being bounded is not a suite — it is the fraction of a run's life spent measuring instead of working. An eighth each way is a quarter of the wall at the very worst, and the worst is rare: the second reading is taken only when the tree changed.

Variables

This section is empty.

Functions

func Adjacent

func Adjacent(root string, focus Focus) (paths []string, core int, ok bool)

Adjacent is the checks that sit next to a change, and it decides that BY STRUCTURE.

It did not, once, and the cost is measured. textual s8 touched `_log.py`, `_rich_log.py`, `widget.py` and `messages.py`; the reader flattened every name to its letters and asked whether a test file's text CONTAINED one, so the stem `log` matched `dialog`, `catalog`, `logic` and `logging` wherever they appeared. The selection came back as forty files spanning tests/animations, command_palette, css, directory_tree, document, footer and input — a third of the suite, none of it about this change — and the reading was killed at its ceiling of 1m53s naming nothing at all. A SUBSTRING IS NOT A RELATIONSHIP.

Two structural relationships, in this rank:

  1. The test file NAMED AFTER the touched file, by the runner's own naming convention — `test_<stem>.py`, `<stem>_test.go`, `<stem>.test.ts` — with the stem compared whole and never as a fragment; and the test files sitting in the same directory as the touched file.
  2. The test files whose IMPORT STATEMENTS resolve to the touched module — `from textual.widgets._rich_log import RichLog`, and equally `from textual.widgets import RichLog`, because the package's own `__init__.py` says that name comes from that file. For JavaScript a relative specifier is resolved against the importing file's own directory. Only import lines are read, and only whole identifiers match, so `Log` never matches inside `Logger` and `log` never matches inside `dialog`.

Paths come back relative to root — which for a member rung is the package's own directory, so the selection drops straight onto a command run there — with rank 1 before rank 2 and each rank sorted inside itself. That order is what survives the cap, so a selection cut to fit keeps the checks the change is actually in.

core is how many of them are rank 1 — the checks the change is IN, as opposed to the ones that merely import it. It is what a reading cut at its ceiling narrows back to, because that is the smallest selection that is still a reading of this change rather than of its neighbourhood.

ok is false when the focus names nothing, when nothing adjacent was found, or when the walk hit its bound before finding anything. All three mean the same thing to the caller: THERE IS NO SCOPED READING TO TAKE HERE, take the whole one. A scoped reading that guessed would be a reading of a suite nobody chose.

func CheckIdentity

func CheckIdentity(name string) string

CheckIdentity is WHICH CHECK A NAME NAMES, and it is the only place in this program that decides that.

A CHECK HAS ONE IDENTITY. The same check is read twice by different readers — out of a runner's output by ReportedTests and FailingTests, out of its own source by DeclaredChecks — and those two readings are put together: the gate unions the checks a run DECLARED with the checks the suite REPORTED to ask what the change covers, and unions the declarations a diff REMOVED with the names a roster stopped reporting to ask what it deleted (internal/revision/acceptance.go). Where the two readers spell one check two ways it is counted twice in both unions — the same test arriving as `test_headers` and as `tests/api_test.py::test_headers` tells the gate a behaviour is covered twice, and names one deletion as two.

The identity is THE BARE NAME, because it is the only spelling BOTH readers can reach. A declaration reader sees a `def`, a `func`, a `void` or an `it(...)`; it never sees the import path, the class, the node-id path, the describe() nesting or the subtest suffix a runner prints around it, and no amount of reading source recovers them. So every qualification a runner adds is stripped here, in this one function, and nowhere else.

THIS IS THE READING OF A NAME A RUNNER PRINTED. A name read out of SOURCE goes through declaredIdentity, which is this reading with the nesting chain left alone, because a quoted description IS the leaf and the ` > ` inside `it("renders a > b")` is two words of it. The two are one function under two names, and the difference is the one thing a reader can know that this function cannot: where the name came from.

WHAT IS NOT DONE HERE, deliberately: a roster keeps the runner's own qualified spelling. A name is two things — an identity and a LOCATION — and SplitReplaced reads the location out of it to tell a check that was rewritten under its own describe path from one that was deleted, which is a distinction that cost happy-dom's s13 run four repair rounds. Reducing every roster to bare names would take that reading away. So the identity is derived where two readers meet (UniqueChecks) rather than imposed on the readers themselves.

func CheckSubject

func CheckSubject(name string) (string, bool)

CheckSubject is what a check is about: its parent path, plus the leading code-shaped tokens of its leaf title.

ok is false where the name carries NO hierarchy — no separator, and a leaf that opens with prose. A TAP line reading `the widget renders` names one flat thing, there is nothing in it to compare a sibling against, and this mechanism is absent rather than guessing: such a name subtracts exactly as it always did. FAILSAFE clause 1 in the direction that costs nothing.

The subject is returned as a PREFIX of the name itself rather than as a rebuilt string, so two names carrying the same subject carry it byte for byte and the comparison is an equality rather than a normalisation.

func Consumers

func Consumers(root string, names []string, changed []string) map[string][]Site

Consumers is where the project itself uses these names, OUTSIDE the lines this run changed, with the syntactic shape of each use.

One walk for every name rather than one walk per name: the walk is what this costs, and a settlement weighing eight definitions must not read the tree eight times.

A site is a WHOLE-IDENTIFIER occurrence — namesIdentifier's rule, the one that keeps `Log` out of `Logger` — of the name as the surface reader spells it, with an instance marker taken off, because `Igel().results_path` is reached by writing `.results_path` and the parentheses are this program's own notation. A dotted or scoped name is matched whole, which is deliberately strict: a caller that reaches a class attribute through `self` spells something this cannot recognise, and not recognising it costs a silence rather than a wrong finding.

A LINE IN A FILE THIS RUN CHANGED IS NOT A CONSUMER. It is the work itself, or it sits beside the work in a file the run was editing, and counting either would report a run's own code as evidence against it. Excluding the whole file rather than the changed lines costs real consumers in a large edited file — which is a silence, and silence is the direction this reading is wrong in everywhere else.

func DeclaredChecks

func DeclaredChecks(source string) []string

DeclaredChecks names every check a body of text declares, in the order it declares them, without repeats.

It reads source rather than output, so it is the one reader here that works on a change nobody has run — which is what makes a diff answer the coverage question at all.

Its names are CHECK IDENTITIES — read out of source by declaredIdentity, which is CheckIdentity's own reading with the one difference source makes: nothing here is a nesting chain, so `it("renders a > b")` declares `renders a > b` and not `b`. Source carries no import path, no class and no node id to qualify a declaration with, so a declaration is otherwise already bare; passing it through that reading is what makes this a stated law rather than a coincidence, and it is what lets the caller that matters deduplicate these names against a runner's roster and get one entry per check (internal/revision/acceptance.go, verify.UniqueChecks).

The order is THE ORDER OF THE TEXT, and it is read off the offsets rather than off the loop below: the patterns are walked one at a time, so a file holding two of the shapes — a suite that spells some of its checks `it` and the skipped ones `xit` — came back grouped by shape and not by line. A doc that promised declaration order over a body that sorted was two statements about one list; the file's own order is the one kept, because it is how a person reads the change, and every caller that needs a set uses Subtract or UniqueChecks, both order-stable in their own argument.

func FailingTests

func FailingTests(output string) []string

FailingTests reads every test identity a runner named as failing, sorted and deduplicated so two runs of one suite compare as sets rather than as transcripts.

func ForgetBaselines

func ForgetBaselines()

ForgetBaselines drops everything remembered. Its only callers are tests, which share a process with each other and would otherwise inherit one another's trees.

func JobKey

func JobKey(request string) string

JobKey is the identity a baseline is remembered against: a digest of the person's own request, whitespace-normalised.

The request is the one thing every leaf of a job holds identically and no two jobs share — a continuation bought by the gate, an escalated retry and the first attempt are all working on the same ask, and the next errand in the same directory is not. It is digested rather than kept whole because this is a map key held for the life of a process and a request can be pages long.

func LostNames

func LostNames(root string, baseline Surface, record []string) (lost []string, compared int)

LostNames is the public names a tree spelled before this work and does not spell now: one baseline surface, one record of what changed, and the tree as it stands.

IT IS THE WHOLE SETTLEMENT AND IT LIVES HERE BECAUSE IT HAS TWO CALLERS. The leaf takes it against the reading it holds; the delivery gate takes it against the JOB's baseline, because the leaf that lost the name and the node that is judged are routinely not the same node — igel s14's three grown leaves each journaled `lost: 3` and both of that job's gates cited a missing file and nothing else. Two spellings of one settlement would be two answers to the question of what a run deleted.

compared is how many changed source files the two readings were compared across, and zero is the one answer a caller must be able to tell from "nothing was lost": it says there was no comparison, not that there was a clean one.

func NamedPaths

func NamedPaths(text string) []string

NamedPaths lists, in order and without repeats, the paths a piece of text names.

func NamedSubjects

func NamedSubjects(text string) []string

NamedSubjects is what a request is ABOUT, as the names it uses: the paths it spells out, and the identifiers it names in the repository's own spelling.

The second half is the repair for happy-dom s8, whose request names `IntersectionObserver`, `IntersectionObserverEntry`, `observe()` and `takeRecords()` and does not contain one path — so a focus built from paths alone was empty, no package was ever chosen, and the whole reading was taken at the repository root and killed at its ceiling.

The third half is the repair for the one measured here. A REQUEST THAT NAMES A DIRECTORY HAS NAMED ITS SCOPE, and a directory is spelled with slashes and no extension, so neither of the two readers above could see one: the errand that said `go test ./internal/subharness/ -count=1` produced an empty focus and a reading of the whole repository. See namedDirectories.

Nothing here decides anything on its own: a name is only a subject once Locate has matched it, whole, to a file or a directory the workspace holds.

func NewCommandFailure

func NewCommandFailure(beforeRed bool, beforeIdentities, afterIdentities []string) ([]string, bool)

NewCommandFailure reports whether a red validation command contains a failure this work introduced. A command that was green before is new red in its entirety. When it was red on both sides, names supplied by the command are compared so one old failure cannot hide a different new one. If either red output supplies no parseable identity, the pair remains uncertain: the command was already red, and silence cannot identify what moved.

func NewFailures

func NewFailures(before, after []string) []string

NewFailures names the checks that were green before this work and are red after it.

It is set subtraction and nothing else: order-stable in `after`'s own order, deduped, and pure. A repository that arrives already red is the repository's problem — a correct one-line fix to spf13/cobra was thrown away once because a gate read a suite's ABSOLUTE state as a verdict on the change, and the 2 in `make all exited 2` came from a test that had been failing before the harness ever opened the directory. Red before and red after subtracts to nothing. Red only after is the change's doing, and it is the one signal a leaf's own new tests cannot carry, because the leaf wrote them.

WHAT THIS FUNCTION DELIBERATELY DOES NOT DECIDE: a red result with NO parseable names is never acquitted by a baseline that also had no names. Two empty readings subtract to nothing here, which is arithmetic, not an acquittal — "the whole suite was red before, so its being red now proves nothing" is the broadest possible acquittal and it is exactly wrong on the run whose whole job was to turn that red suite green. The CALLER weighs the exit statuses and decides; this function only subtracts.

func PatchChecks

func PatchChecks(patch string) (added, removed []string)

PatchChecks reads a unified diff and names the checks it ADDS and the checks it REMOVES.

A line is read for its content and never for its file, because a diff carries no reliable statement about which files are test files: a check moved between two files is added and removed in the same patch and cancels here, which is the honest reading of a move. A check that is only removed is a check that stopped existing, and that is the whole finding docs/design/gate/ACCEPTANCE.md §3 is about — deleting the failing test is the cheapest way there is to make a suite green.

The diff's own headers are skipped: "+++ b/test/foo.test.ts" begins with a plus and declares nothing.

func Qualified

func Qualified(name string) bool

Qualified says this name has an owner — `ScrollBar.position`, `Igel().results_path`, `Type::method` — rather than standing alone at the top level of a module.

func ReadingBudget

func ReadingBudget(wall time.Duration) (time.Duration, bool)

ReadingBudget is what one reading of the project's own verification may spend, given the whole wall its caller was granted.

ok is false when the wall is too short to afford the measurement, which is the refusal above. A ninety-minute wall affords 11m15s a reading; a sixty-second wall affords 7.5s, which is under the floor, so it photographs nothing. The shortest wall that photographs at all is eight minutes.

func RememberBaseline

func RememberBaseline(root, job, tree string, reading Reading)

RememberBaseline records what this job's leaves are measured against, for every leaf of it that follows.

IT REMEMBERS THE REFUSAL AS WELL AS THE READING. Why a reading could not be taken is a fact about the tree, the project and the wall, and none of those change between one round of a job and the next — so a job that could not photograph its tree pays for finding that out ONCE. textual's s6 leaf spent five and a half minutes of its wall on a suite that was killed at the ceiling; without this, every continuation of that job spends the same five and a half minutes to learn the same thing.

tree is the state of the tree the reading is of, as TreeState spells it: what the job had produced or changed when it was taken. It is remembered beside the reading because the ONE question every later reader asks is whether anything has happened since, and the reading itself cannot answer it — a photograph holds no account of the world outside its own frame.

A Reading that says nothing at all — neither taken nor carrying a reason — is not remembered. That is the zero value, it is what a caller that never looked produces, and remembering it would make the next leaf inherit a silence instead of taking the photograph the job still owes.

func ReportedTests

func ReportedTests(output string) []string

ReportedTests is every check identity a runner named, red or green, sorted and deduplicated so two runs of one suite compare as sets.

It is a superset of FailingTests by construction — the same output read through both vocabularies — because a roster that omitted the red half would report every failing check as one that had disappeared.

The names are the RUNNER'S OWN spelling — the node-id path, the describe chain, the subtest suffix — because a roster is read for the location in a name as well as for the check: SplitReplaced tells a rewritten check from a deleted one by the path it sits under. Which check one of these names is the same check as is CheckIdentity's question, and it is asked where a roster meets a reading of source rather than here.

func SkipTree

func SkipTree(name string) bool

SkipTree names the directories that are somebody else's files sitting in this workspace: the harness's own dot-directories, the tooling's, and the dependency installs. A leaf that ran `pip install` produced thousands of files and delivered none of them.

IT IS THE ONE LIST. Three walks in this program ask the same question — the workspace's own record of what a run left behind (internal/exec), the delivery gate settling a named file against the disk (internal/revision), and the two walks in this package — and three lists of "what is not a deliverable" is three answers to one question, which is exactly how a number in this repository drifts. It lives here because this package depends on nothing and the other two already depend on it.

func Subtract

func Subtract(from, remove []string) []string

Subtract is that arithmetic with the meaning left out: the names in `from` that `remove` does not hold, order-stable in `from`'s own order, deduped, and pure.

It is exported and separate because three questions in this system turn out to be one subtraction — which checks this work turned red, which checks stopped being reported, and which check declarations a diff only takes away — and three copies of a four-line loop is how they come to disagree about the empty case. Every caller states the meaning; this states none.

func SurfaceNamed

func SurfaceNamed(names []string) []string

SurfaceNamed is what a finding says out loud: the first few names, and a count for the rest.

func TreeState

func TreeState(root string, record []string) string

TreeState is the workspace's own account of what a job has produced or changed, as one comparable word.

The account is the artifact record — every file the run created or changed, settled against the disk by whoever holds it — and it is digested rather than kept because this is compared, never read: two states are the same state or they are not. The empty string is the honest spelling of an UNTOUCHED tree, which is the state most errands are in for their whole life, and it is what a job that has produced nothing yields at every reader.

A LIST OF NAMES IS NOT A STATE OF A TREE, and reading it as one is how this was first written. A repair round's whole job is usually to rewrite a file the round before it already recorded, so the record's NAMES are identical either side of the work while its BYTES are not — and a state built from names alone would call that tree unchanged and hand the gate a reading taken before the repair. So every recorded path is settled against the disk: its size and its modification time, which is the same before-and-after pair the workspace's own watch uses to decide a file moved (exec.Workspace.RecordChanges).

AND A PATH THE TREE NO LONGER HOLDS IS THE LOUDEST CHANGE THERE IS. A deletion never reaches an artifact list — exec.Workspace.Artifacts holds what the tree still has, deliberately, because the list is also what a person is shown — so a caller that hands a deleted path in a continuation's record would otherwise get the same digest it got before the file went. It folds in as a marker, which is what makes the state answer the question its name asks.

Sorted first, so two accounts of one tree that were assembled in different orders are one state. A path is taken as recorded and resolved against root when it is relative, because both sides of every comparison come from the same recorder and the recorders disagree about which spelling they keep.

func TreeUnchangedSince

func TreeUnchangedSince(root, job, tree string) bool

TreeUnchangedSince says the job has produced or changed nothing since its reading was taken: the tree carries the same account of the work now as it did then.

IT IS THE WHOLE CONDITION FOR NOT LOOKING AGAIN. A reading is a measurement of a tree, so a tree that has not moved has already been measured — and the run that measured it wrote the answer down. Every retake of an unchanged tree is an eighth of a wall spent to reproduce a roster the run is already holding.

It is false where nothing was ever remembered, which is the honest answer: a question about "since" needs a moment to be since, and a caller with none must look rather than assume.

func UnboundWords

func UnboundWords(found []UnboundName) []string

UnboundWords is one reading as the lines a finding, a journal and a brief all spell it: the name, where it is read, and where this reader looked for a binding.

ONE SPELLING, because the leaf takes this reading on its own seam and the gate re-takes it on the tree it judges, and two wordings of one measurement read downstream as two measurements.

func UniqueChecks

func UniqueChecks(names []string) []string

UniqueChecks is a run of check names, read by whichever readers named them, with one entry left per check.

It is the union every caller of the two readers needs and none of them can spell with Subtract, which compares strings: `test_headers` and `tests/api_test.py::test_headers` are two strings and one check. The first spelling of a check wins, and the order is the caller's own — the same contract Subtract states, so a list that holds no duplicate identities comes back exactly as it went in.

Types

type Assertions

type Assertions map[string]string

Assertions is what each check in one file asserts: the declaration's name, folded to lower case, against the text of its assertion statements.

A key that is PRESENT with empty text is a check this reader found and whose assertions weigh nothing it could see. A key that is ABSENT is a check this reader could not find at all. Those are two different answers and the caller spends them differently, which is why this is a map and never a list.

func AssertionsIn

func AssertionsIn(file, body string) Assertions

AssertionsIn reads one file and returns what each check in it asserts.

A nil answer means this program has no reader for the file's language, which is the same silence PublicSurface keeps for the same reason: a language read by guesswork is a language read wrongly, and every wrong reading here becomes a repair round bought against a check that was fine.

The body may be given lower-cased — the callers that already hold a folded copy of a file pass it — so every shape this matches is spelled in a way that case cannot change, and every key is folded on the way in.

func (Assertions) Named

func (a Assertions) Named(identity string) (string, bool)

Named is Text for a runner identity that a runner printed with its groups JOINED BY SPACES rather than by a separator this program can see.

vitest prints `circuit breaker origin keying keys by origin, not path` for a case declared `it("keys by origin, not path")` inside two nested `describe` blocks, and nothing in that string says where the groups end and the case begins. So the identity's own trailing words are tried, longest first, and the first that is a case this file declares is the case. A suffix of one word is not tried: one word matching one case name is a coincidence, and the cost of the wrong case here is a finding about a check nobody wrote.

ofetch s16 is what this is for: forty-seven mapped pairings, every identity in that shape, and the assertion door found not one of them.

func (Assertions) Text

func (a Assertions) Text(check string) (string, bool)

Text is what this check asserts, and whether the check was found at all.

type ChangedDefinition

type ChangedDefinition struct {
	Name string
	File string
	// Before is where the declaration stood in the tree before the job's first
	// change, and After is where it stands now. Both come off the readings
	// themselves rather than off a diff's arithmetic, so both are the
	// declaration and not the neighbourhood it sits in.
	Before    Span
	After     Span
	Consumers []Site
}

ChangedDefinition is one public name this work REWROTE — the name is in both readings and the text of its declaration is not — with where it stood on either side of the work and what still uses it.

func ChangedDefinitions

func ChangedDefinitions(root string, baseline Surface, record []string) []ChangedDefinition

ChangedDefinitions is the public names this work REWROTE: present in the baseline reading and present now, under one file, with a different declaration digest.

It is the same subtraction Removed is, over the same pair of readings, asking the other question. Removed asks which names went; this asks which of the ones that STAYED are no longer the same thing. Neither needs a runner, a diff or a model, and both are scoped to the run's own record for the same reason: a definition that moved in a file nobody touched moved some other way.

A name declared twice under one file — an overload, a conditional re-definition — is passed over rather than guessed at. There is no way to say which of two declarations became which, and a reader that picked one would be reporting an arrangement it invented.

func (ChangedDefinition) Grouped

func (d ChangedDefinition) Grouped() []SiteGroup

Grouped is this definition's consumers by shape, largest group first and each group in file order. It is one reading shared by the block a judge is shown and the row the journal keeps, because two groupings of one list are two answers to one question.

type Declaration

type Declaration struct {
	Name string
	Line int
	End  int
	// Digest is a hash of the declaration's own lines, and it is what makes a
	// definition that KEPT ITS NAME comparable across two readings of a tree.
	//
	// A name comparison answers presence and nothing else, which is the hole
	// igel s12 went through: `configs` was rebound from a dict to an instance of
	// a class the run wrote, `lost: 0` was correct, and twenty-four hidden tests
	// failed on `'Configs' object does not support item assignment`. Two
	// readings of one tree already exist on every belt this program has; this is
	// the one field that lets them answer whether a definition MOVED as well as
	// whether it is gone.
	//
	// Blank lines are skipped and trailing whitespace is trimmed, so a file run
	// through a formatter does not read as a project rewritten. Nothing else is
	// forgiven: this is a hash of source text and never a reading of meaning.
	Digest uint64
}

Declaration is one public name and WHERE the tree spells it: the line the declaration opens on, and the last line of it, both 1-based and inclusive.

The span is read by the SAME walk that reads the name, and that is the whole reason it lives here rather than in a reader of its own. A second walk that decided where a declaration sits would eventually disagree with the one that decided the name exists, and everything downstream that asks whether a run touched a DEFINITION rather than a file has to be able to trust that the two answers are about the same thing.

It is as conservative as the names are. Where a reader cannot see where a declaration ends it says the declaration's own line, which can only make an overlap harder to find — the safe direction, because the cost of a definition invented here is a finding about work nobody did.

func DeclarationsIn

func DeclarationsIn(file, body string) []Declaration

DeclarationsIn is one file's public declarations with their spans, read by whichever reader its language shape calls for.

A language with no reader here declares NOTHING rather than something guessed at, which is the same silence publicNames keeps and for the same reason.

func (Declaration) Overlaps

func (d Declaration) Overlaps(from, to int) bool

Overlaps answers whether this declaration covers any line of a range.

func (Declaration) Spans

func (d Declaration) Spans(line int) bool

Spans answers whether this declaration covers a line of the file.

type Entrypoint

type Entrypoint struct {
	Kind    EntrypointKind `json:"kind"`
	Command string         `json:"command"`
	Workdir string         `json:"workdir,omitempty"`
	Source  string         `json:"source"`
}

type EntrypointKind

type EntrypointKind string
const (
	KindBuild EntrypointKind = "build"
	KindTest  EntrypointKind = "test"
)

type Focus

type Focus []string

Focus is what this job is about, as paths: what the person's request named, and what the record shows the work touched.

It is supplied by the caller because only the caller knows which of those it holds — a first leaf has the request and no diff, a continuation and the delivery gate have both. An empty Focus is a job that named nothing, and its reading is of the whole project, which is what every reading here was before this existed.

func ChangedSources

func ChangedSources(root string, record []string) Focus

ChangedSources is the other half of the same record: every file the run left behind that is NOT a check.

It is what the second reading is aimed at. The scope of the first is a reading of the REQUEST, settled before the work existed and inherited by every round — and a request is not a diff. textual s10 asked for `Log and RichLog`, which resolved to `_rich_log.py` and could not resolve `Log` at all, so both readings ran `tests/test_concurrency.py tests/test_textlog.py`; the change touched `_log.py` and `_rich_log.py`, and `tests/test_log.py` — which the repository already had, beside the file the work changed — was never read on either side. The diff is the one account of where the work actually went, and it exists by the time the second reading is taken.

func Locate

func Locate(root string, focus Focus) Focus

Locate resolves what a request SAYS into paths the workspace actually holds.

It exists because happy-dom s8 took its whole reading at the repository root and never once looked at `packages/happy-dom`, where the work was. Nothing was wrong with the workspace declaration or with the nearest-manifest walk: THE FOCUS WAS EMPTY. A focus was derived only from paths a request spells out, and that request spells out none — it says "Implement `observe()`, `unobserve()`, `disconnect()` and `takeRecords()`", names `IntersectionObserver` and `IntersectionObserverEntry`, and never writes a single path. So no package was touched as far as the reader knew, the ladder had only root rungs, and the root's `npx vitest run` was killed at its ceiling naming nothing.

A request that names a thing this repository has a FILE for is a request about that file, and that is a structural fact rather than a guess. Three ways a name resolves, all of them whole-name equality and none of them a substring:

  • a path the workspace holds outright;
  • a bare file name, resolved to wherever the workspace keeps it;
  • a distinctive identifier whose spelling IS a source file's name under the ecosystem's own convention — `IntersectionObserver` is `IntersectionObserver.ts`, and `RichLog` is `_rich_log.py`, because CamelCase and snake_case are two spellings of one name and a leading underscore is Python's mark for a private module.

And a fourth, which is a place rather than a file: A DIRECTORY THE REQUEST SPELLS AND THE WORKSPACE HOLDS IS A SUBJECT, and the package it is stands as the scope of the reading. `go test ./internal/subharness/ -count=1` names one package of a repository of two hundred, and until this it named nothing at all. See namedDirectories and heldPlaces.

Unresolved entries are kept as they were: they cost nothing and a caller may have handed a path this walk could not reach.

func MissingFrom

func MissingFrom(root string, record []string) Focus

MissingFrom names the paths in a record that the tree no longer holds.

It is the deletion case, and it belongs beside ChangedSources rather than inside it: that reader keeps only what is still there, because a scoped test command handed a path that has gone collects nothing at all. The symbol-level half wants the opposite — a public module that was deleted has lost every public name it had, and there is no file left to read that off.

func OwnChecks

func OwnChecks(root string, record []string) Focus

OwnChecks is every check file in a record of what a run left behind, as workspace-relative paths in stable order.

It is the world's own answer to "which of these are checks" — the record is the artifact registry settled against the filesystem, so a file is here because the tree gained or changed it, whatever wrote it — and a path is a check by the runner's own naming convention and by nothing else. It is deliberately not the worker's account of what it tested: that is a claim about checks the same worker wrote, which is the thing the whole gate exists not to weigh.

func (Focus) Within

func (f Focus) Within(dir string) Focus

Within is this focus as a reading taken inside dir would see it: the entries that fall under dir, with dir taken off the front.

It exists because a focus is recorded once, against the workspace, and read in several places — the root and every package a monorepo declares. A path that does not fall under dir is not dropped silently; it is simply not part of that package's change, which is the fact the scoped reading there is a reading of.

type Format

type Format string

Format is how one reading's bytes are turned into check identities.

It is a property of the RUNNER and not of the language: vitest and jest print the same document because one copied the other's reporter, and mocha under `--reporter tap` prints what the shared vocabulary already reads. Three formats cover every runner this program has met, and a runner that matches none of them is read as plain text, which is what every runner was read as before this existed.

const (
	// FormatPlain is the runners' shared human-readable vocabulary — the
	// PASS/FAIL lines failing.go and roster.go already know. It is the floor
	// every other format falls back to, never an absence of one.
	FormatPlain Format = "plain"
	// FormatNodeJSON is the document vitest's `--reporter=json` and jest's
	// `--json` both print: one entry per file, each holding one assertion
	// result per check, each naming the check and how it went.
	FormatNodeJSON Format = "node-json"
	// FormatGoJSON is `go test -json`: one JSON object per line, each an
	// action on a package or a named test.
	FormatGoJSON Format = "go-json"
)

func (Format) Read

func (f Format) Read(output string) (reported, failing []string, ok bool)

Read turns one reading's bytes into the roster and the red half of it.

ok is false when the format's own parser found nothing it recognised, and the caller then reads the same bytes as plain text. THAT FALLBACK IS THE WHOLE FAIL-SAFE DIRECTION OF THIS FILE: a runner that ignored the flag, a version whose reporter moved, a suite that died before printing its document — each of them lands exactly where every reading landed before strategies existed, and none of them can turn a red suite green.

type Member

type Member struct {
	Dir string `json:"dir,omitempty"`
	// Source is the declaration this member was read out of — the manifest key,
	// the workspace file, the go.work. It is the sentence an autopsy reads to
	// see whether the reader looked in the right place, and it is the same
	// field Strategy.Source is for the same reason.
	Source string `json:"source,omitempty"`
}

Member is one package of a workspace: where it lives, and what declared it.

Dir is workspace-relative and slash-spelled, so it drops straight into Strategy.Workdir; the empty string is the root itself, which is what a project that declares no workspace has exactly one of.

func MemberFor

func MemberFor(root, touched string) Member

MemberFor is the package one path belongs to: the nearest directory at or above it that carries a manifest, bounded by the workspace root.

It is the nearest-declaration walk a package manager itself does, and it is the whole of how the record of what a job touched becomes the place a reading is taken. A path outside the workspace, or one with no manifest above it, belongs to the root — which is the honest answer and the one every reading gave before members existed.

func Members

func Members(root string) []Member

Members is every package this workspace declares itself to be made of, in the order the declaration gives them, with the root last.

The root is ALWAYS a member and always last. A monorepo's root usually holds a runnable command of its own — happy-dom's is the turbo fan-out — and it is the honest last rung of a ladder whose earlier rungs are packages: if reading the package the work touched names nothing, reading the whole thing is what is left to try.

A project that declares no workspace returns the root alone, which is what every reader here did before this file existed.

func TouchedMembers

func TouchedMembers(root string, paths []string) []Member

TouchedMembers is the packages a job's own record of what it touched falls in, most-touched first, bounded at memberLimit.

Most-touched first is the ladder's order and it is the only ordering that is a fact about the work: a job that changed nine files in one package and one in another is a job about the first. Ties break on the path so two readings of one record are one ladder.

type Pace

type Pace struct {
	Spent time.Duration
	Files int
}

Pace is what a reading that was CUT measured about how fast this project's checks run: the time it spent, and how many check files it had been asked for.

It is the only thing a run ever learns about the speed of the machine under it, and it is a fact about the project and the machine rather than about the round — so it is remembered against the job with the baseline and spent by the next round, which is what "never the same blind ceiling twice" means. A zero value is a job that has measured nothing, and its reading is sized the way every reading here was.

func (Pace) Affords

func (p Pace) Affords(budget time.Duration) int

Affords is how many check files this pace says fit in a budget, and it is written to be honest about what a CUT measured rather than to look precise.

A cut proves one thing: this selection costs MORE than Spent. So Spent over Files is a lower bound on the per-file cost, and the count it yields is a CEILING on what fits — never a target. Taken as a target it says a reading killed at 1m53s over forty files can be retaken over thirty-six, which is the same reading again.

So the ceiling is one of two bounds and the other is a halving, which is the only certain thing about a size that did not fit: the next one must be materially smaller. A tenth is held back on top for the difference between an average and a worst case.

func (Pace) Known

func (p Pace) Known() bool

Known says this pace was actually measured.

type Plan

type Plan struct {
	Entrypoints []Entrypoint `json:"entrypoints"`
	// BuildExpected reports whether this project is required to have a
	// build/typecheck step. True for any accountable workspace — including one
	// whose ecosystem we do not recognize — so the gate stays fail-closed; a
	// plain Python package is the one case we can positively identify as
	// having nothing to compile.
	BuildExpected bool `json:"buildExpected"`
	// TestExpected reports whether this project is required to have a test
	// step. True for any accountable workspace: unlike a build, no ecosystem
	// is exempt from having tests. Both flags are false only for a workspace
	// that is not accountable at all (see accountableWorkspace).
	TestExpected bool `json:"testExpected"`
}

func Discover

func Discover(workspace string) Plan

Discover follows the auditor convention in src/baked/agents/auditor.md: prefer CI, then repository instructions, declared scripts/manifests, and finally ecosystem defaults. Each role gets one project-wide entrypoint.

type Reading

type Reading struct {
	Plan   Plan          `json:"plan,omitzero"`
	Budget time.Duration `json:"budget,omitempty"`
	// Strategy is the rung that was reached — the command that ran, or the one
	// that would have. It is set even when nothing was read, because "what
	// would have run" is half of why nothing did.
	Strategy Strategy `json:"strategy,omitzero"`
	// Unread is why there is no reading, in one sentence, and it is the whole
	// repair of the silence this type used to keep. A zero Reading has four
	// causes — a project that declares no verification, a wall too short to
	// afford one, a shell the preamble cannot be trusted in, and a command
	// killed at its ceiling — and downstream they mean different things and
	// cost different amounts. textual's s6 leaf spent five and a half minutes
	// on the fourth of them and left no trace of having done so.
	//
	// It is empty when Taken is true. NOBODY LOOKED IS A FACT, AND A FACT
	// ABOUT THE RUN REACHES THE RECORD (FAILSAFE.md clause 4).
	Unread string `json:"unread,omitempty"`
	// Partial says the reading that was taken was CUT: the command was killed
	// at its ceiling having already named some checks. It is a real roster and
	// it is not a comparable one — the checks it never reached are missing
	// because the clock ran out, and subtracting them would report the whole
	// tail of a suite as checks that disappeared.
	//
	// It exists because throwing the names away was worse. ink s7's `npx ava
	// --tap` was killed at 1m53s having streamed part of its 922 checks; the
	// whole reading was discarded, the round-2 gate had no roster at all, and a
	// deliverable at 13 of 25 hidden checks passed with nothing to weigh. A
	// PARTIAL ROSTER ANSWERS "DOES A CHECK FOR THIS EXIST" PERFECTLY WELL; it
	// answers "did this work break something" not at all, and those are two
	// questions.
	Partial bool `json:"partial,omitempty"`
	// CutAfter is how long the cut reading ran before it was killed. It is what
	// the run learned about this project's PACE, and it is remembered against
	// the job for the same reason the refusal is: a container running amd64
	// under qemu is five to ten times slower than the machine the budget's
	// arithmetic assumes, and a job that discovered that must not spend another
	// eighth of its wall discovering it again.
	CutAfter time.Duration `json:"cut_after,omitempty"`
	Before   Result        `json:"before,omitzero"`
	// After is the second reading, of the tree as it was handed over. It is
	// separate from Before rather than replacing it because the whole value of
	// a photograph is the subtraction, and a run holding one reading cannot
	// tell a check this work broke from a check the repository arrived broken.
	After      Result `json:"after,omitzero"`
	Taken      bool   `json:"taken,omitempty"`
	AfterTaken bool   `json:"after_taken,omitempty"`
	// Surface is the OTHER half of the photograph: the public names the tree
	// spelled before the job's first change, by file.
	//
	// It is here rather than beside itself because it is one measurement of one
	// tree at one moment, taken with the check-level reading and inherited by
	// every round of the job for the identical reason — a repair round standing
	// in a tree its own job already changed must be compared against what the
	// JOB found, not against what the previous round left.
	//
	// It never reaches the journal whole: a repository's public surface is tens
	// of thousands of short strings and what a reader wants is the DIFFERENCE.
	// See Surface.Removed, and store.EventSurface.
	Surface Surface `json:"-"`
}

Reading is a run's photograph of the project's own verification: what the suite said before the work, what it said after, and the entrypoint and budget both readings were taken with.

A zero value — which is what an unaffordable wall, an undiscoverable entrypoint or a hung first reading all produce — is a reading that was never taken. Taken says which of the two it is, because an empty Before reads downstream as NO CLAIM and never as NOBODY LOOKED, and the whole reason this type is carried rather than reduced to a list of names is that the delivery gate needs to tell those apart.

It travels on the outcome so the gate can weigh what the world said instead of what the deliverable claims the world said. The gate may also fill After itself, on Budget, when the work moved after the last photograph was taken.

func BaselineFor

func BaselineFor(root, job string) (Reading, bool)

BaselineFor is what this job settled about its own tree before its first change: the reading it took, or the reason it could not take one.

ok is false only for the first leaf of a job. A later leaf inherits whichever answer the first one reached, and inherits it rather than re-deriving it, because both answers are facts about a tree that has since moved.

func BaselineOf

func BaselineOf(root, job string) (Reading, string, bool)

BaselineOf is the same answer with the tree-state it was taken against, for the two readers that have to know whether anything has happened since.

The pair exists rather than one call with three results because most readers want the reading and nothing else — the coverage settlement, the consumer scan, the removed-surface comparison — and a caller that has to ignore a return value is a caller that will one day ignore the wrong one.

func Photograph

func Photograph(ctx context.Context, root string, wall time.Duration, focus Focus, pace Pace) Reading

Photograph takes the reading a job is measured against: the tree as it stands before anything has changed it.

It walks the strategy ladder (see ReadingStrategies) inside ONE budget. A rung that names nothing has told us nothing about the suite — textual's own `make test` exits in eight seconds on a pytest plugin the image does not have — so the next rung is tried with whatever budget is left. The LAST rung's answer is taken whatever it named, because a runner that genuinely reports no identities is a real reading with an empty roster, and treating that as no reading is the exact short-circuit that let fifty-two stated behaviours go unasked.

focus is what this job is about, and it is what decides HOW MUCH of the project each rung reads — see scope.go. An empty focus is a job that named nothing, and every rung of its ladder is a reading of the whole project, which is what every reading here was before scopes existed.

The Reading it returns is always meaningful: Taken says a reading exists, and Unread says in one sentence why one does not.

func (Reading) Declared

func (r Reading) Declared() bool

Declared says the project SAID how it is checked, whether or not a reading was taken of it.

It is the difference between the two silences that used to be one. A project with no verification at all leaves the coverage question unanswerable and nobody is at fault; a project that declares a suite this run could not read leaves it unanswered, which is a fact about the run and must not deliver as whole. ink s7 passed at 13 of 25 hidden checks on the second of those.

func (Reading) OnAnUnchangedTree

func (r Reading) OnAnUnchangedTree() (Reading, bool)

OnAnUnchangedTree is this photograph with the reading before the work standing as the reading of the finished tree.

IT IS NOT AN ASSUMPTION, IT IS THE SAME TREE. The caller has established that the job changed no file since the first reading was taken — the workspace's own record of what the work produced is the same list it was then — so the suite would be run a second time over the identical bytes to produce the identical roster. The measured errand paid for that four times: `go test -json ./...` over 4,587 tests, killed at its ceiling, on a tree the leaf had been told to change nothing in.

ok is false where there is nothing to stand: a reading that was never taken, and one whose after half a real run has already filled in.

func (Reading) OwnFailing

func (r Reading) OwnFailing() []string

OwnFailing names the red checks that FIRST APPEARED AFTER THE BASELINE: the ones this run wrote itself, and did not get passing.

It is the other half of what the failure list used to be read as, and it is a different finding with different words. A leaf whose own new checks are red has not finished; a leaf that turned somebody else's check red has broken the repository. Both are worth a repair round and only one of them is true of a run that wrote thirty new tests and got twelve of them right.

Only where the baseline kept a roster, for the reason Regressed states: with no roster there is no way to tell a new check from an old one, and inventing the distinction would put every failure in a runner that prints only failures into this list instead of the other.

func (Reading) Pace

func (r Reading) Pace() Pace

Pace is what this reading measured about the project's speed, if it measured anything. Only a cut reading does: a reading that finished says how long its own selection took and nothing about the ceiling it never reached.

func (Reading) Regressed

func (r Reading) Regressed() []string

Regressed names the checks that were green before this work and are red after it, or nothing when there is no pair of readings to subtract.

func (Reading) Replaced

func (r Reading) Replaced() []Replacement

Replaced names the checks that stopped being reported and the checks that took their subject over, before to after.

It is a record and never a finding: nothing follows from a rewritten check except that it was not a removed one. It is carried so an autopsy of a run that raised no removal finding can see WHY — a mechanism that silently declines to convict is indistinguishable from one that was never reached (FAILSAFE.md clause 4).

func (Reading) Retakeable

func (r Reading) Retakeable() bool

Retakeable says this remembered answer is one a later round should NOT simply inherit: a scoped reading cut at its ceiling having named nothing, WHERE THE PACE IT MEASURED AFFORDS A STRICTLY SMALLER READING.

Everything else about a failed reading is a fact about the tree, the project and the wall, and none of those move between rounds — that is why the refusal is remembered at all. A ceiling hit by a selection THIS PROGRAM CHOSE is not one of them: it is a fact about a size, the cut measured the pace that would have chosen a better one, and inheriting it is how textual s8 spent its one reading on forty files and then declined to look again.

AND A SECOND IDENTICAL ATTEMPT CANNOT FINISH WHERE THE FIRST DID NOT. The retake is worth buying only where there is a smaller selection to buy: a reading of everything the entrypoint covers has no narrower scope to fall to, and a scoped one whose pace affords no fewer files than it already ran would spend another eighth of the wall on the same command. Both of those are the same reading again, and this is where they are refused rather than in each of the two callers that would otherwise have to know it.

The budget the retake is weighed against is the one this reading was taken on, which is the most generous a retake can be handed: the gate takes its own share of whatever wall is left, and that is smaller. So a size this refuses was never affordable.

func (Reading) Vanished

func (r Reading) Vanished() []string

Vanished names the checks the suite reported before this work, did not report after it, and whose SUBJECT no check after it covers — deleted, or skipped, and never merely rewritten.

It asks the question only when BOTH rosters named something. Two empty rosters subtract to nothing, which is arithmetic and not an acquittal, and a single empty one is a runner that printed no identities rather than a suite that lost all of them — reading either as a disappearance would convict every project whose runner is quiet on success. Same fail-safe direction as NewFailures, for the same reason.

A NAME IS NOT A SUBJECT. The subtraction alone reports a rewritten check as a deleted one, and a run's whole job is often to rewrite checks: happy-dom's v4-flash s13 replaced four stubs with real ones under the identical describe path, and every repair round it bought re-raised the same removal finding against a tree the grader scored 9 of 9. See SplitReplaced and Replaced.

type Replacement

type Replacement struct {
	Before string   `json:"before"`
	After  []string `json:"after,omitempty"`
}

Replacement is one check that stopped being reported and the checks that took its subject over.

func SplitReplaced

func SplitReplaced(gone, after []string) (removed []string, replaced []Replacement)

SplitReplaced sorts the names a roster stopped reporting into the ones NOTHING covers and the ones a later check does.

THE RULE: A CHECK THAT EXISTED BEFORE AND IS ABSENT AFTER IS REMOVED ONLY IF NOTHING AFTER IT COVERS ITS SUBJECT. A check whose subject the after roster still names was rewritten, not deleted — and whether the thing that replaced it PASSES is a different question with a different finding already behind it (see Reading.OwnFailing).

A name with no hierarchy to read is removed, exactly as it always was.

type Result

type Result struct {
	// Entrypoint is the command that was actually run, carried so a second
	// reading can be taken of the same thing rather than of a re-discovery.
	Entrypoint Entrypoint
	// Exit is the process's own exit status, or -1 when the process never got
	// far enough to have one.
	Exit int
	// TimedOut says the command was killed at the caller's ceiling without ever
	// exiting. A HUNG SUITE IS AN INCOMPLETE OBSERVATION, NOT A RED ONE: it
	// names nothing, so nothing can be subtracted from it and nothing can be
	// attributed to it.
	TimedOut bool
	// Strategy is HOW this reading was taken: the command that ran, the runner
	// underneath it, and the way its output was read. It is carried so the
	// second reading can be taken the same way as the first — two readings
	// taken with two different commands subtract to noise — and so an autopsy
	// of a run that named nothing can see where the reader looked.
	Strategy Strategy
	// ReadAsPlain says the strategy's own reader found nothing it recognised
	// and the shared PASS/FAIL vocabulary read the same bytes instead. It is
	// the fail-safe firing, and it is recorded rather than silent because a
	// roster that came back through the fallback is a roster whose runner did
	// not answer the way this program expected.
	ReadAsPlain bool
	// Uncollected says the runner produced NO TEST RECORD OF ITS OWN: this
	// strategy asked for a machine-readable report and the reader for that
	// format found none in what came back.
	//
	// It is the shape a suite that failed to COLLECT has — an import that will
	// not resolve, a config that will not load, a syntax error in a test file —
	// and it is a different fact from a suite that ran and went red. ofetch's
	// nemotron n1 run hit it four times: `vitest run --reporter=json` printed no
	// JSON, the shared vocabulary scraped one word out of the error text, and a
	// reading naming ONE check was subtracted against a baseline that named 28.
	//
	// Error is the tail of what the runner said instead, so the record carries
	// the reason rather than a count of nothing.
	Uncollected bool
	Error       string
	// Failing is every test identity the runner named, read by [FailingTests].
	Failing []string
	// Reported is every test identity the runner named at all, red or green,
	// read by [ReportedTests]. It is the roster, and it answers the question
	// redness cannot: WHICH CHECKS EXIST. A check in one reading's roster and
	// absent from the next stopped existing between them, which is the one
	// signal that catches a worker deleting the test that was failing it.
	Reported []string
}

Result is one reading of one entrypoint.

func RunReading

func RunReading(
	ctx context.Context, workspace string, strategy Strategy, timeout time.Duration,
) (Result, bool)

RunReading takes one reading with a strategy that is already decided.

It exists separately from RunTests because the SECOND reading of a pair must be taken exactly as the first was. Re-deriving the strategy there would let a worker that edited its own test script change what the after-reading measures, which is the tamper the photograph exists to catch, and it would silently re-scope a comparison whenever a project's declarations moved under it.

ok is false when the strategy names no command, or when this machine has no shell the preamble can be trusted in. A CAPABILITY THAT CANNOT WORK IS ABSENT RATHER THAN BROKEN (CLAUDE.md) — the caller gets no reading rather than an empty one it would have to tell apart from a green suite.

func RunTests

func RunTests(
	ctx context.Context, workspace string, plan Plan, timeout time.Duration, focus Focus,
) (Result, bool)

RunTests takes one reading of the project's own checks: it decides HOW the reading is taken from what the project declares (see ReadingStrategy), runs that, and reads the identities out of what it printed.

ok is false when the plan declares no test entrypoint at all. A PROJECT THAT DOES NOT SAY HOW IT IS CHECKED IS NOT A PROJECT THIS CAN CHECK.

type Site

type Site struct {
	File  string
	Line  int
	Text  string
	Shape string
}

Site is one place the project uses a name, outside the files the run changed.

Text is the whole line, trimmed, because the shape is a reading and the line is the evidence for it: a reader who disagrees with the shape can see what it was read off. Shape is the closed set below and nothing else.

func (Site) Where

func (s Site) Where() string

Where is the site as everything downstream spells it.

type SiteGroup

type SiteGroup struct {
	Shape string
	Sites []Site
}

SiteGroup is one shape of use and the sites that have it, biggest group first.

type Span

type Span struct {
	From int
	To   int
}

Span is a range of lines, 1-based and inclusive at both ends.

func (Span) Empty

func (s Span) Empty() bool

Empty says this span names no line.

func (Span) Words

func (s Span) Words() string

Words is the span as a person reads it: "lines 12–40", or "line 12".

type Strategy

type Strategy struct {
	// Command is what is actually run, whole.
	Command string `json:"command"`
	Workdir string `json:"workdir,omitempty"`
	// Runner names the program underneath, in the spelling the project uses.
	// Empty means none was found and the project's own script is being run as
	// it stands.
	Runner string `json:"runner,omitempty"`
	// Read is how the output is turned into names.
	Read Format `json:"read"`
	// Source is where the runner was found — the script whose body names it,
	// the manifest that depends on it, the config file that configures it. It
	// is the sentence an autopsy reads to see whether the reader looked in the
	// right place.
	Source string `json:"source,omitempty"`
	// Declared is the project's own entrypoint, kept beside the command that
	// was actually run so the two can be compared. Where a lifecycle script
	// wraps the runner these differ, and the difference is the news.
	Declared string `json:"declared,omitempty"`
	// Scope is HOW MUCH of the project this reading covers: ScopeWhole, or the
	// count of files a scoped reading selected. See scope.go for why a reading
	// is scoped before it is bounded, and Reading.comparable for why the scope
	// is part of this strategy's identity rather than a note beside it.
	Scope string `json:"scope,omitempty"`
	// Base and Selected are Command taken apart: the runner's own invocation,
	// and the checks it was told to run. They are here so a reading CUT AT ITS
	// CEILING can be taken again over fewer of them — the measured pace of a
	// suite is spent divided by Selected, and that is the only thing a run ever
	// learns about how fast the machine under it is.
	//
	// All three fields are written in one place (scopedStrategy) and nothing
	// else may write one without the others; Command is what runs, and these
	// two are what it was built out of.
	Base     string   `json:"-"`
	Selected []string `json:"-"`
	// Core is how many of Selected are the checks the change is IN, as opposed
	// to the ones that merely import what it touched. It is the floor a reading
	// cut at its ceiling narrows back to.
	Core int `json:"-"`
}

Strategy is how one reading is taken: the exact command, where it runs, how its output is read, and — the part an autopsy needs — WHY this command rather than the one the project declared.

It is pinned on the first reading and re-used verbatim for the second, because two readings taken with two different commands subtract to noise. Re-deriving it would also hand a worker that edited its own test script the power to change what the after-reading measures, which is the tamper this whole photograph exists to catch.

func ChangedWorkStrategy

func ChangedWorkStrategy(workspace string, plan Plan, record []string) (Strategy, bool)

ChangedWorkStrategy is a reading aimed at the DIFF and nothing else: the checks the run wrote, and the checks beside the source files it changed.

It is the second reading's fallback for a job whose first reading was of the WHOLE suite and could not finish it. A whole rung that was killed at its ceiling has proved this project's suite does not fit the wall; running it again on the finished tree spends the same eighth to learn the same thing, and the run ends with no roster of the work it just did. ofetch s10 took six readings, every one of them `whole`, because the request's focus resolved to nothing the workspace held. The change itself always resolves — it is a list of files that exist — so where the whole reading does not fit, the diff is the reading that does.

The pair it produces is deliberately NOT comparable: a reading of a handful of files is a subset of a reading of everything, covers refuses it in that direction, and Reading.Regressed answers nothing rather than reporting every check outside the selection as vanished. What it buys is the ROSTER — which checks exist for the work that was just done — which is the half the coverage settlement spends and the half a cut whole reading has none of.

ok is false when the record names nothing the tree still holds, or when this project's runner cannot be told what to run.

func ReadingStrategies

func ReadingStrategies(workspace string, plan Plan, focus Focus) ([]Strategy, bool)

ReadingStrategies is the ladder of ways this project's checks can be read, most specific first.

There is a ladder because the most specific rung can fail in a way that says nothing about the suite. textual's own `make test` is `poetry run pytest tests/ -n 16 --dist=loadgroup` and the task image has no pytest-xdist, so that invocation exits in eight seconds on `unrecognized arguments: -n` — a reading that names nothing, of a suite that was never asked to run. A reader with one rung takes that for the whole answer; a reader with a ladder drops to the runner's own invocation and reads the suite.

The ladder has two dimensions, and both of them are "most specific first".

WHERE, from Members. A monorepo's root command is a fan-out: happy-dom's `npm test` is `turbo run test`, which at an uncompiled base commit dies inside turbo having named no check of any package, while the runner that names its 7,260 checks sits in packages/happy-dom's own manifest. So the packages the work touched are read first, most-touched first, and the root is the last place tried rather than the only one. A project that declares no workspace has exactly one place and this dimension collapses to nothing.

HOW MUCH, from Adjacent. Inside each place the SCOPED rung comes first — the runner handed the checks that sit next to the change — and the whole-suite rungs come after it. textual's whole-repository reading collects 3,422 tests and takes 793 seconds against a budget of 5m30s, so the whole rung was the only rung and it never returned an answer at all.

The rungs within one place, and why they are in this order:

  1. The runner, handed the checks adjacent to the change. It is built from the runner's OWN invocation rather than from the project's script, because what is being replaced is the project's own scope — appending a selection to a command that already names `tests/` selects both.
  2. The runner as the PROJECT'S OWN script or recipe invokes it, with the project's flags kept. This is the most faithful whole reading there is, and it is the only rung that knows the project scoped its suite to `tests/`.
  3. The runner as it invokes itself, taken from what the project declares it depends on and configures. It drops the project's flags, which is the point: a flag that needs a plugin the environment lacks is what put us here.
  4. The project's declared entrypoint, run as it stands and read as plain text. This is what every reading in this program was before strategies existed, and it is the floor rather than an absence of one.

Identical rungs are collapsed, so a project whose script already spells the runner plainly produces one strategy and one reading.

ok is false exactly when there was nothing anywhere to run.

func ReadingStrategy

func ReadingStrategy(workspace string, plan Plan, focus Focus) (Strategy, bool)

ReadingStrategy is the first rung of ReadingStrategies: the most faithful way this project's checks can be read. It is what a caller taking exactly one reading uses.

func (Strategy) Empty

func (s Strategy) Empty() bool

Empty reports a strategy that names no command, which is what an undiscovered entrypoint produces.

func (Strategy) WithChangedWork

func (s Strategy) WithChangedWork(workspace string, record []string) (Strategy, bool)

WithChangedWork widens a scoped reading to take in the work THE RUN ITSELF DID, named from the record of what it left behind: the checks it wrote, and the checks that sit next to the source files it changed.

It is the one thing a scope decided before the work cannot know, and igel s8 is what it costs. That job's focus resolved to one file, so both its readings were `pytest tests/test_igel/test_igel.py` and both named the same two checks — while the run wrote `tests/test_igel/test_feature_schema.py` and `tests/test_igel/test_integration.py`, about forty checks, and no reading ever ran one of them. The coverage mapping had a roster of two to match a whole checklist against, and the before-and-after could not move because the only thing that changed was invisible to both halves.

> THE RUN'S OWN CHECKS ARE ALWAYS IN SCOPE, ON EVERY ROUND, AND THEY COME > FROM THE WORLD'S RECORD RATHER THAN FROM THE WORKER'S ACCOUNT.

AND SO ARE THE CHECKS BESIDE WHAT IT CHANGED. The first reading's scope is a reading of the REQUEST — it has to be, because at the moment it is taken there is no diff — and a request is not a diff. textual s10 asked for `Log and RichLog`; `RichLog` resolved to `_rich_log.py` and `Log` resolved to nothing, so both readings ran `tests/test_concurrency.py tests/test_textlog.py` while the change touched `_log.py` and `_rich_log.py` and `tests/test_log.py` — a file the repository already had, sitting beside the one the work changed — was read on neither side. By the time the second reading is taken the diff exists, and it is the only account of where the work actually went. The source files in the record go back through the same structural adjacency the scope was built with (Adjacent), so what joins is the checks named after them and the checks whose imports resolve to them, and never a name that merely looks alike.

record is the artifact record — every file the run created or changed, whatever wrote it — and a path in it is a check by the runner's own naming convention and by nothing else. Adding files can only GROW the roster, which is why the after reading may be wider than the before one and the comparison still holds: see covers, and Reading.Regressed, where a check the before reading never ran cannot have regressed.

ok is false for a reading of the whole suite, which already holds them, and when the record adds nothing this reading is not already running.

type Surface

type Surface map[string][]Declaration

Surface is the public names a tree spells, keyed by the file that spells them.

Per FILE rather than per project, because that is what makes the comparison affordable: the finished tree is re-read only where the run's own record says it changed something, and a name that moved from one file to another is a removal from the first and an addition to the second — which is what a rename is, and what it should read as.

func PublicSurface

func PublicSurface(root string) Surface

PublicSurface reads the public names of the source files under root that this program can parse with certainty, walking the whole tree inside one budget.

It is the BASELINE half, and it is taken with the check-level reading, before the job's first change.

func SurfaceOf

func SurfaceOf(root string, files Focus) Surface

SurfaceOf reads the public names of NAMED files only, which is what the finished tree is read for: the run's own record of what it changed.

A file the record names and the tree no longer holds contributes nothing here, so every public name its baseline entry held is reported removed — which is what deleting a module does.

func (Surface) Names

func (s Surface) Names(file string) []string

Names is one file's public names, which is what a finding spells and what the journal keeps.

func (Surface) Removed

func (baseline Surface) Removed(now Surface, files Focus) []string

Removed names every public name the baseline held that the finished tree does not, looking ONLY at the files named — the run's own record of what it changed.

Scoping to the record is what keeps this a measurement of the WORK rather than of the repository. A name that vanished from a file nobody touched vanished some other way, and reporting it would hand a leaf a finding about something it never did.

A rename reads as a removal, and correctly: the old name is gone, every caller of it is broken, and whether something similar was added in its place is a judgement this makes no attempt at. The added name is visible in the same two readings for whoever wants it.

type SurfaceIndex

type SurfaceIndex struct {
	// contains filtered or unexported fields
}

SurfaceIndex is a tree's public names keyed by the words they are made of, so a sentence can be asked which of them it names.

func IndexSurface

func IndexSurface(surface Surface) SurfaceIndex

IndexSurface reads a tree's surface into that vocabulary.

func (SurfaceIndex) Holds

func (i SurfaceIndex) Holds(symbol string) (string, bool)

Holds confirms a name the request already spelled distinctively: the tree declares it, either whole or as the member of something.

It is what keeps a hyphenated English compound out. `full-width` is spelled exactly like a name and is not one; the tree is what says so, and no list of words is consulted.

func (SurfaceIndex) Spoken

func (i SurfaceIndex) Spoken(text string) []string

Spoken is every public name this sentence names in words, in the order the sentence names them.

TWO WORDS AT LEAST, AND A QUALIFIED NAME. One word of a sentence is a word — "position", "log", "size", "write" — and reading it as a name of the tree would make an observable of nearly every noun a request contains. And a name with only one part is a TYPE: textual's request says "after users scroll up", textual declares a `ScrollUp` message, and the two have nothing to do with each other. `ScrollBar.position` and `RichLog.write` are members somebody can read a value off, and a person who spelled a bare class name spelled it as one word, where the symbol reader already has it.

type UnboundName

type UnboundName struct {
	// File and Line are where the reference is, in the record's own spelling.
	File string
	Line int
	// Name is the reference as a person writes it: `RichLog._size_known` for an
	// attribute, the bare binding for an import.
	Name string
	// Scope is the class or module the name should have lived in.
	Scope string
	// Ground is where this reader looked and did not find it.
	Ground string
	// Text is the reference's own line, trimmed, so a reader who disagrees with
	// the finding can see exactly what it was read off.
	Text string
}

UnboundName is one name a source this run changed reads, that the tree binds nowhere.

Ground is the evidence of ABSENCE in the words a reader can check — "assigned nowhere in class RichLog, tree-wide" — because a finding about something that is not there is only as good as its account of where it looked.

func UnboundNamed

func UnboundNamed(found []UnboundName) []UnboundName

UnboundNamed is what a finding says out loud: the first few references, and the rest left to the journal.

func UnboundReferences

func UnboundReferences(root string, record []string) []UnboundName

UnboundReferences is every name the run's CHANGED SOURCES read that the tree defines nowhere.

The record is the run's own account of what it left behind, settled against the filesystem, so this is a reading of the WORK and never of the repository: a dangling reference in a file nobody touched was dangling before the run started and is somebody else's finding.

Every silence favours the work. No record, no changed source in a language with a reader, an index the budget could not finish, a file that cannot be read, a scope holding any construct that binds names dynamically — each of those adds nothing at all.

func (UnboundName) Where

func (u UnboundName) Where() string

Where is the site as everything downstream spells it.

func (UnboundName) Words

func (u UnboundName) Words() string

Words is one unbound reference as a person reads it.

Jump to

Keyboard shortcuts

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