chore(lab): scope the bench to the repository and remove the campaign - #301
Merged
Conversation
The campaign held no fact that was not either a decision about one repository or a directory name. Its spend ceiling was never enforced (budget.Ceiling had no caller), its arm matrix drove nothing (plan.Expand fed a printer), and its run tree was a folder above the repository's own. Everything it grouped was already per repository: the run tree, the authoring cycles, the position, the verdicts. - `sense-lab repo` no longer takes `-campaign`. Admission answers to the repository alone, which is what the loop is: `sense-lab repo owner/name` clones, pins, scans and records. Run trees live under `runs/repos/<id>`. - `sense-lab status` reports every repository under `-runs`, with each one's spend against its own ceiling. `sense-lab plan -repo <id>` expands that repository's bench, declared in `lab/benches/<id>.json` rather than `lab/campaigns/<key>/campaign.json`. - The spend ceiling is now wired: 40 paid runs per repository over its lifetime, refused by `probe` before anything spawns, read from the tree on every call rather than counted in memory. `budget.ErrCeiling` makes a refusal tellable from a failed read, and `probe` answers with the refusal code. There is no flag to raise it, and `status` lost its `-ceiling` flag so the page cannot state a ceiling nothing enforces. - `budget.Read` is unchanged: it always walked whatever root it was handed. - The handoff phase declared `reads: campaign.json`, a file that never existed in any run tree. It now declares `attempts/`, which is what the plan reads. - LAWS: the spend law is scoped by repository rather than campaign, and ONE REPO AT A TIME records that its gate is NOT BUILT, since the row it was going to be read from is gone. Local run trees were moved by hand (`runs/` is gitignored): the repository to `runs/repos/<id>`, `records/` up to `runs/records/`, because a finding is about a Sense surface and not about the repository it was seen in. Stale paths in record JSON were repointed; raw transcripts were left untouched.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
The page and the crank worked the same tree out separately, and they disagreed. `status` derived the cycle from the numbered directories itself, so a repository admitted and scanned but with no cycle directory yet read as cycle 0, reached none, awaiting none, with no resume line, while `position` (which the crank routes on) read the same tree as cycle 1 awaiting author. Measured on mastodon straight after admission. status.Repo now embeds position.Position rather than re-deriving it, so there is one reader. Its own walk, its artifact check and its index lookup are gone with it. Two things the page gains from the position it was not carrying: the standing, in the words position gives it, so a PAY nothing will spend, an agent that misbehaved and an agent that died are visible rather than absent; and a resume line gated on Ready rather than on "not parked and awaiting something", which is what let a parked repository read as awaiting a phase.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nothing in the Sense binary changes. This is the bench instrument, and it gets
one idea smaller: a repository is the unit of work. Benching one now takes a
single command with no setup decision in front of it, and the spend ceiling
that was written down but never enforced now actually stops a paid run.
Problem
sense-labcarried a container above the repository called a campaign, and itrequired one before anything could happen:
sense-lab repo mastodon/mastodonrefused with
-campaign names the run tree the index artifact belongs to. Thatis a decision demanded before it can be informed, in the run path, on a crank
that is supposed to run unattended.
The container held no fact of its own. Its spend ceiling was never enforced
(
budget.Ceilinghad no caller outside its own test), its arm matrix drovenothing (
plan.Expandhas one caller, which prints a table), and its judge pinhas no consumer. Everything it grouped was already per repository: the run
tree, the authoring cycles, the position, the verdicts, the attempts. What was
left was a directory name, and it made the instrument harder to explain than
the thing it measures.
Summary
Removes the campaign and scopes the bench to the repository: its own run tree,
its own arms, its own spend ceiling of 40 paid runs, which
probenow refusesto spend past.
Changes
Admission and position
sense-lab repodrops-campaign. Run trees live underruns/repos/<id>,reached by
-runswith a default nobody needs to type. The originalinvocation now works:
sense-lab repo owner/nameresolves, clones, pins,scans and records.
sense-lab statusdrops-campaignfor-runsand reports every repositoryunder it, each with its own spend against its own ceiling.
The bench matrix
plan.Campaignbecomesplan.Bench, losingKeyandRepos. Onerepository, its subjects, its arms, its pinned judge.
sense-lab plan -campaign <key>becomessense-lab plan -repo <id>, readinglab/benches/<id>.jsoninstead oflab/campaigns/<key>/campaign.json.The spend ceiling, wired
probebeforeanything spawns. It is read off the tree on every call rather than counted in
memory, so a loop resumed after a crash cannot spend the budget twice.
budget.ErrCeilingis a sentinel, so a refusal is tellable from a tree thatcould not be read.
probeanswers with its refusal code rather than itserror code.
statuslost its-ceilingflag: one constant feedsthe page and the refusal, so the page cannot state a ceiling nothing holds.
Correctness found on the way
reads: campaign.json, a file that has neverexisted in any run tree. It now declares
attempts/, which is what the planactually reads.
Architecture Highlights
budget.Readis unchanged. It always walked whatever root it was handed, andonly its argument moved from a campaign to a repository, which is the sign
this was a naming convention rather than a mechanism.
runs/records/rather than moving under a repository.A finding is about a Sense surface, not about the repository it was seen in,
and scattering findings per tree is the exact failure the record package was
built to close.
inside it. The two have different authors and lifetimes: what a repository is
gets written by admission, how it is measured gets written by a person.
Breaking Changes
nothing to migrate in this repo.
sense-lab repo -campaign <dir>is gone. Drop the flag.sense-lab status -campaign <dir>becomessense-lab status(or-runs).sense-lab status -ceiling <n>is gone.sense-lab plan -campaign <key>becomessense-lab plan -repo <id>, andlab/campaigns/<key>/campaign.jsonbecomeslab/benches/<id>.jsonwithrepoin place ofkeyand noreposlist.runs/campaigns/<key>/<repo>moves toruns/repos/<repo>, and itsrecords/moves toruns/records/. No codemigrates it, and nothing reads the old path.
Test Plan
directory is created
has spent nothing
another, with mini-bench runs excluded as unpaid
errors.Is, so it cannot beconfused with an unreadable tree
statusreports the default root without being told, and rejects-ceilingis refused, as is an unknown field in it
sense-lab repo -show mastodon/mastodonresolves, prints the positionand exits with the shown code, with no campaign anywhere
go test ./...passesmake cigreen: per-file coverage gate passes, 96.1% total, 0 lintissues, complexity ledger at 0
qlty checkreports no issues, with no smells in any changed file