016 US5: git_log — the history the repository already keeps - #16
Merged
Conversation
`git_log` answers two questions a security reader asks constantly and
bee could not: what changed here, and which commit introduced this line.
`gix` is the engine, so the exec allowlist stays empty — no `git` binary
is admitted to run this, and the answer does not depend on which `git`
happens to be installed or on parsing output meant for humans.
Same seam as `search` and `ast_grep`: the library reads inside a
scope-joined child (`bee gitlog-worker`), because `.git` is a directory
of files like any other and a policy that denies it means it. Reading
history in the harness would read around the sandbox.
The care is all in one place. Three outcomes look identical from outside
a child that printed nothing — no commits touch the path, the path is
not in a repository, the request could not be answered — so the worker
separates them by exit code (0 / 3 / 4) and the wrapper maps those to
Completed / Unavailable{NotARepository} / Failed. Grepping the
diagnostic would tie that distinction to wording; an empty history is
also spelled out in words rather than left as silence.
Blame is tested against both halves: line 3 (changed by the second
commit) and line 1 (still the first). A blame that always answered HEAD
would pass on one and fail the other.
Read-only by construction — nothing here writes an object, a ref, or a
config entry.
Closes T054–T057.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The last deferred user story from 016 that was worth building. Independent of #15 (017) — different files, no conflicts, either order merges.
What it does
git_loganswers two questions a security reader asks constantly and bee could not: what changed here (mode: "log"— the commits touching a path, newest first) and which commit introduced this line (mode: "blame").gixis the engine, per 016's two-tier rule: the value is the implementation, not someone's curated corpus, so bee links the crate. The exec allowlist stays empty — nogitbinary is admitted to run this — and the answer does not depend on whichgitis installed or on parsing output formatted for humans.Where it runs
In a scope-joined child (
bee gitlog-worker), exec'd through the sandbox exactly likesearch-workerandastgrep-worker..gitis a directory of files like any other; a policy that denies it means it, and reading history in the harness would be reading around the sandbox.The part that needed care
Three outcomes are indistinguishable from outside a child that printed nothing:
no commits in this repository touch that pathdid not run: … is not inside a repositoryfailed: <diagnostic>The worker separates them by exit code, and the wrapper maps those to
Completed/Unavailable { NotARepository }/Failed. Grepping the diagnostic would tie the distinction to wording any later edit could break. The empty case is spelled out in a sentence rather than left as silence — FR-012 is about a reader being able to tell "found nothing" from "did not run" at a glance.NotARepositorywas already in the outcome enum: 016 laid the groundwork and left the tool unbuilt.Tests
The fixture is a real repository built with the
gitCLI — a.gitdirectory cannot be checked into this repo, and a hand-built one would assert against bee's idea of a repository rather than git's. Two commits, the second changing exactly one line, which is what makes blame falsifiable: line 3 must be the second commit and line 1 must still be the first. A blame that always answered HEAD passes one and fails the other.Also covered: the untracked-file case (empty history, exit 0 — the case the refusal must stay distinguishable from), the limit taking from the newest end, and a line past the end of the file being a diagnostic rather than an invented attribution.
Housekeeping
git_logjoinsSEC_TOOLS, so a build without--features gitlogregisters the refusingNotCompiledInstub rather than rejecting the name as unknown. README's feature table and quickstart get a §US5 walkthrough; the "Deferred to follow-on" section now lists only US6 (CodeQL), which stays deferred deliberately — its traced languages would mean admitting every compiler and linker a build invokes, the widening SC-006 exists to prevent.cargo fmt/clippy -D warningsclean; full workspace suite green at default andsecfeatures.🤖 Generated with Claude Code