Skip to content

bench(lab): admit a repository with one command - #298

Merged
luuuc merged 2 commits into
mainfrom
lab/09-01-admit-a-repository
Aug 19, 2026
Merged

bench(lab): admit a repository with one command#298
luuuc merged 2 commits into
mainfrom
lab/09-01-admit-a-repository

Conversation

@luuuc

@luuuc luuuc commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Problem

Admitting a repository to the bench is three manual acts today and nothing checks that they agree with each other: a human clones it, hand-writes lab/repos/<id>.json with a commit copied out of the clone, and runs sense scan over it.

Two things go wrong and only one of them is loud. A sha typed into the json that is not the sha the clone sits at produces a worktree at the wrong tree for every run afterwards, and nothing says so. A scan that indexed half the tree produces a repository that reads as dark when the tool simply did not finish.

Summary

sense-lab repo <handle|url|path> does the whole thing: resolve, clone, pin, index, record.

The resolver is pure and its order is first match wins — an admitted id, a path on disk, owner/name, then a url. A local directory named owner/name resolves as the path, because a directory that is there is evidence and a handle is a guess.

Nothing is written before the resolution is printed. Everything that decides runs first and touches nothing; the decision is announced; only then does anything reach a disk. The recorded pin is read back out of the clone rather than carried over from the request.

Ownership decides what may be moved: a clone the lab made and that drifted goes back to its pin, and a clone somebody handed in is read and never written to, with a mismatch refused and its reason given.

Re-running on an admitted repository admits nothing and prints where it stands, because the crank will call this on every invocation.

Changes

  • lab/internal/repo: the pure resolver, the checkout (clone, adopt, correct or refuse) and the index phase, which runs sense scan and reads its counts through the MCP server in the checkout
  • lab/internal/cli/repocmd.go: the command, its announcement, and the two records it writes — the index artifact and the repository file, the latter written last and only when there is an index to read its languages off
  • catalog.Repo gains checkout, whose absence is the ownership record
  • lab/README.md and lab/repos/README.md: the first step of the shortest useful path is now this command

Test plan

  • make ci green: coverage floor with no new exception, zero complexity suppressions, lint clean
  • new files hold 98.8–100% line coverage
  • five mutations that a first draft of the tests let through are now killed, each verified by making the mutation and watching a named test fail: dropping -embed from the scan, asking the server outside the checkout, deleting the MCP handshake, selecting the reply without its id, and reusing an earlier reply's document for a call that failed
  • the exchange is pinned against the real sense binary, not only against the stand-in
  • end to end against a real repository: clone, pin, index, record, then a second run that admits nothing

luuuc added 2 commits August 19, 2026 09:07
Admission was three manual acts that nothing checked against each other: a
clone, a hand-written repository file with a sha copied out of it, and a scan.
A sha in the json that is not the sha the clone sits at gives every later run a
worktree at the wrong tree, and nothing about a result says so.

The resolver is pure and its order is first match wins: an admitted id, a path
on disk, `owner/name`, then a url. The ambiguous case resolves as the path,
because a directory that is there is evidence and a handle is a guess.

Everything that decides runs before anything is written, and the decision is
announced in between: a caller whose announce returns an error stops with the
directory as it found it. The pin is then read back out of the tree rather than
carried over from the request.

Ownership decides what may be moved. A clone the lab made and that drifted goes
back to its pin; a clone somebody handed in is read and never written to, and a
mismatch there is refused with its reason.

The index phase runs the product binary the way a user would and reads its
counts through the MCP server, in the checkout, because that is the channel a
benched agent actually has. A scan that indexed nothing writes an artifact that
says so.
`sense-lab repo <handle|url|path>` is the whole admission: it prints what it
resolved, clones under the lab's own root, records the revision the clone is
actually at, indexes it and writes the index artifact.

The repository file is written last and only when there is an index to read its
languages off, so a failed clone, an unreachable url or a scan that indexed
nothing leaves nothing behind that a later phase would read as ready.

Re-running on an admitted repository admits nothing and prints where it stands.
The crank calls this on every invocation, so admission has to be idempotent for
that to be safe.

The repository record gains `checkout`, and its absence is the ownership rule:
a repository the lab cloned has none, and is one the lab may move back to its
pin.
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.37304% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
lab/internal/repo/checkout.go 98.07% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@luuuc
luuuc merged commit 29cdd79 into main Aug 19, 2026
7 checks passed
@luuuc
luuuc deleted the lab/09-01-admit-a-repository branch August 19, 2026 15:47
@luuuc
luuuc restored the lab/09-01-admit-a-repository branch August 19, 2026 15:48
@luuuc
luuuc deleted the lab/09-01-admit-a-repository branch August 19, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant