Development record
A one-package change is checked in minutes, not the whole suite
Press Release
A change to one package is checked in minutes, because abcd reruns only what the change could have affected. Maya's agent fixes a bug in one package and runs the check before pushing. Instead of an hour of every test in the project twice over, abcd reuses every result that cannot have changed and reruns the rest, and the report says how many tests ran and how many were reused. Nothing the check guarded is skipped: a test whose inputs changed always runs, and a test declared as reading what abcd cannot see always runs too.
Why This Matters
On 2026-11-01 a full check of abcd's own repository reused no cached test result at all: every package ran from scratch, then again under the race detector. Go's test cache keys on the test binary, and each worktree's absolute source paths change it; with
-trimpaththe same unchanged package in a second worktree came straight from the cache.-trimpathcannot simply be switched on, because nine test files find the repository throughruntime.Callerand fail under it (iss-2611011343052330). On a busy day the check waited one to two hours for its turn on the machine, so every minute it does not repeat is a minute a waiting agent gets back. The product thinker relies on these checks as the only human in the loop, so the saving must come from not repeating what cannot have changed, never from running fewer of the checks that matter. A change to records alone already takes a shorter path, which still runs the tests that read records (dcn-2608160000000002 ruled that skipping them is fail-open).
Mechanism
We expect most unchanged packages to be reused because Go already records, per package, the test binary, the flags, and the files and environment variables a test reads, and reuses a result only when all are unchanged (cmd/go test caching); the change is to stop defeating it with worktree paths. It would be shown wrong by a measured run in which few results are reused: Go keys an opened file on its size and modification time, and a fresh worktree gives every file a new time, so a test that reads the repository's tree reruns in a new worktree even when nothing it reads changed. The measure decides how large the saving is before any figure is claimed.
Scope Conditions
- The person's own machine, with one Go cache and one fixed check directory (~/.abcd.noindex/tests/<root-sha>/) shared by every worktree and clone of the repository on that account, one check at a time; hosted CI is out of scope here, because a fresh checkout's new file times defeat the cache there too (left to a follow-up intent).
- Go repositories; another language keeps the records-only path and whatever reuse its own tooling offers.
- Tests that are deterministic given their inputs; a test that reads state the cache cannot see (a subprocess's output, a binary it builds, the clock, the network) is declared and always reruns.
- The full check, uncached, still runs where it runs today in hosted CI (pull request, merge queue, nightly); this intent changes what the person's machine repeats, not what lands untested.
Acceptance Criteria
- Given a commit whose check has passed in one worktree, when the same commit is checked in a fresh worktree on the same machine, then every test whose inputs are unchanged is reused rather than rerun, and the check's report counts the tests it ran and the tests it reused.
- Given a test that reads an input the result cache cannot see (a file a subprocess reads, or a file outside the repository), when it is named on the list of always-rerun tests kept on the default branch, then it reruns on every check; and given a release cut, when its gates run, then every test runs without reuse on the tree being tagged.
- Given a change to records alone, when its check runs, then only the tests whose inputs include those records rerun, and the report says which ran and why.
- Given the test helpers that find the repository through
runtime.Caller, when the whole suite runs under-trimpath, then every test passes, and no test finds the repository through its own source path. - Given a check, when it ends, then its report names how many packages ran and how many were reused, for the unit stage and the race stage alike.
- Given ten consecutive landings after this ships, when their reports are read, then the share of reused packages and the check time are recorded against the baseline of 2026-11-01 (no reuse), and that figure, not an estimate, is the saving stated.
Decisions
- 2026-11-01, the product thinker in the planning interview: reuse of unchanged test results becomes its own intent, shipped first. This intent refines itd-2610261025516272 by taking its three reuse criteria, the first and third verbatim and the second reworded to name the list on the default branch; that draft keeps a pointer and the landing route.
- 2026-11-01, the product thinker: hosted CI reuse (restoring file times in a fresh checkout) is left to a follow-up intent; this one covers the person's machine.
- 2026-11-01, the product thinker: the always-rerun tests are named on a list on the default branch, never by a test or a change itself.
- 2026-11-01, the product thinker: the press release, the mechanism claim, the four scope conditions and all six acceptance criteria were confirmed, the second worded to name the list on the default branch and its release-cut half confirmed separately; impact is fix.
- 2026-11-02, the product thinker: the test stages run from one fixed check directory per repository, ~/.abcd.noindex/tests/<root-sha>/, outside every working tree as a verifier's copy must be, and one check uses it at a time; this keeps criterion 1 for tests that open or stat files in the tree, which Go keys by their absolute path.
- 2026-11-02, after the interview, from the landing reviews: the press release's 'a test abcd cannot see the inputs of always runs too' was made precise as 'a test declared as reading what abcd cannot see always runs too' (declared meaning named on the list kept on the default branch), since only a declared test can be rerun on purpose; an undeclared test that reads a subprocess, the clock or the network is reused on the person's machine and caught only by the hosted full run. The product thinker confirmed the edited wording on 2026-11-02.
- 2026-11-01, the product thinker: reuse is planned alone and first. The drafts itd-2610110940216682 (every change checked in full once) and itd-2610262141001890 (how many checks run at once) are kept separate from it and are to be planned together later; itd-2610262141001890 waits on itd-2610262140595217, so bundling them with reuse would have held reuse back.
Open Questions
All resolved; the rulings are in the Decisions section.
- resolved: reuse on the person's machine is this intent; restoring file times so hosted CI can reuse results is a follow-up intent of its own (2026-11-01).
- resolved: the tests that always rerun are named on a list kept on the default branch, so a change cannot declare its own tests away (2026-11-01).
- resolved: the test stages run from one fixed check directory per repository, ~/.abcd.noindex/tests/<root-sha>/, used by one check at a time, so criterion 1 holds for tests that read the tree (2026-11-02).
Decomposition
Hand-run four-piece table, 2026-11-01, revised after two pre-interview reviews (design and feasibility; record discipline), which found the first draft repeated three of itd-2610261025516272's criteria, contradicted dcn-2608160000000002 by skipping the suite for record-only changes, and bundled macOS scheduling and batching that belong elsewhere.
| Part | Kind | Home |
|---|---|---|
| reuse of unchanged results across worktrees on the person's machine, the declared always-rerun tests, the reuse count, the measured saving | capability | this intent |
| a change never declares its own tests away; the list of always-rerun tests is read from the default branch | trust rule | already standing in the principle evaluator-outside-the-loop; cited, no new ADR |
-trimpath, the runtime.Caller sweep |
plumbing | iss-2611011343052330, delivered by this intent |
| macOS off every landing in a private repository; one landing check for a feature built in several steps | capability | stays in itd-2610261025516272 |
Verdict: FILE-AS-IS after the revision. Typed links: refines itd-2610261025516272, moving its three reuse criteria here verbatim, the parent keeping a pointer; builds_on itd-2611011325403127 for the landing report. Advisory reversal flags: none.
Audit Notes
Empty. Populated by intent-auditor when intent moves to shipped/.
Grounds
- pursued: checks wait one to two hours for the machine and each repeats work that cannot have changed; we expect a one-package check to take minutes, and ten landings that show little reuse would show it wrong
Frontmatter
| id | itd-2611011325421304 |
|---|---|
| type | intent |
| lifecycle | planned |
| kind | standalone |
| severity | minor |
.abcd/development/intents/planned/itd-2611011325421304-a-landing-runs-the-tests-its-change-can.md
open on GitHub ↗ · commit history ↗
References1
- itd-2611011325403127Every landing shows what it cost and the next run's estimatebuilds on
Referenced by2
- iss-2611011343052330Go's test cache is never reused across worktrees, so every preflight runs all packages twice from scratch. A full preflight on 2026-11-01 reported 0 cached results of 133 packages. The cache keys on the test binary, and each worktree's absolute source paths change it: the same unchanged package in a second worktree re-ran, while with -trimpath it came straight from the cache. -trimpath cannot simply be switched on: nine test files locate the repository through runtime.Caller (internal/core/lint/releasereceipts_test.go, internal/core/launch/payload_completeness_test.go, internal/core/launch/scaffold/scaffold_test.go, and six in internal/surface/cli: hooks_sessionstart, hook_scripts, barerender, hooks_selfprovision, bootstrap, githook_prepush), and under -trimpath every one fails, since the path becomes the module path (open github.com/intentdriven/abcd/.github/workflows/release.yml: no such file or directory). Across the last 60 merges, about two thirds of all test time re-ran results that could not have changed.related
- spc-2611012047503720A one-package change is checked in minutes, not the whole suiteimplemented by
mentions10
- dcn-26081600000000022026-08-16 — CI inert-path skip gate (iss-234): the inert allowlist is `docs/**`, `.abcd/development/**`, `.abcd/work/**`, plus exactly README.md, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, ACKNOWLEDGEMENTS.md, LICENSE, LICENSE.md; everything else — notably the harness routers (AGENTS.md/CLAUDE.md/GEMINI.md), commands/, agents/, hooks/, .abcd/*.json, .github/**, evals/, scripts/, Makefile, Go source — is non-inert, and every unknown or degraded outcome (non-PR event, empty diff, unreadable base, aborted or failed classifier) runs the full matrix, fail closed and loudly. Deviation from the capture's skippable list, maintainer-confirmed 2026-08-16: the ubuntu unit lane ALWAYS runs — lifeboat brief-coverage, glossary-index and README-grounding tests assert against the live tree inside the allowlist (reproduced: a prose-only brief edit turns TestEveryBriefSectionHasARow red while record-lint and docs-lint stay green), so skipping `go test ./...` on an inert change is fail-open; what stands down is the macOS leg's heavy steps, the race lane, smoke, and zizmor. The skipped-conclusion-satisfies-ruleset behaviour is unverified until the rehearsal PR passes; nothing arms auto-merge on it before that. Rejected: a fromJSON dynamic matrix (a never-reporting `check (macos-latest)` wedges every PR) and a marketplace paths-filter action (plain git suffices, no new pinned dependency).
- dcn-26110207154919282026-11-02 — The product thinker ruled on the morning of 2026-11-02, in an interview another session relayed and one question put here: the test stages run from one fixed check directory per repository, ~/.abcd.noindex/tests/<root-sha>/, used by one check at a time, so results carry over between worktrees and criterion 1 of itd-2611011325421304 holds for tests that read the tree; a key's budget caps count the whole key, every session on that key pauses together at a cap, and spend never passes it, which replaces the 2026-11-01 reading in dcn-2611012123470476 that a limit stops only the session that hit it; what happens at a cap is a per-repository setting, pausing by default, with moving to a second key the person named for that purpose as the alternative and the subscription never; the terminal interview fix iss-2611011402496418 is lowered to minor so the build loop takes it on the API key, a ruling the product thinker gave directly to the session that records it, in answer to a question it put, which that session's transcript in the person's transcript store carries; and a command agents cannot run that admits one named issue above minor to the build loop is to be built next (iss-2611020305525945). The same morning they confirmed the edited wording of itd-2611011325421304's press release, that a test declared as reading what abcd cannot see always runs, in place of the wording confirmed at its interview.
- iss-2610311225001256abcd build itd-2610170638184486 is refused at the peers check because the worktree sota-open-intents, on branch research/sota-open-intents, holds the intent in drafts/ with its own edits, while this checkout has it in planned/. The branch's last commit is 2026-10-23 and it is not merged, so the hold is a research copy a week stale, and the refusal gives neither its age nor a way past it (merge it, or rebase it onto the planned record; removing the worktree is the person's act alone, since it deletes the copy's local tier); an unattended build cannot tell an abandoned peer from live work and is blocked indefinitely.
- itd-2610110940216682Every change is checked in full once, on exactly what lands
- itd-2610261025516272Private repos land checked work without renting CI
- itd-2610262140595217abcd records how each preflight on a machine behaved
- itd-2610262141001890abcd adjusts how many preflights run at once from what it recorded
- itd-2611011325428560A solo private repo can self-attest its gates, labelled so
- itd-2611011325430933A machine the person owns checks agents' work independently
- itd-2611011325449761New repos offer a choice of check profiles with their costs