feat(delivery): record the branch and PR on the spec, and keep attribution out of the record - #29
Merged
Merged
Conversation
…ution out of the record Two halves of one question — what the record of a delivery says. **The spec records where it is being built.** A branch was the one part of this methodology that left no trace in the artifacts: the spec said which boxes were ticked, git said a branch had been unmerged for three weeks, and nothing joined the two, so "which of these actually shipped" was answerable only by somebody holding both halves. Under `autonomy: auto` that is nobody. Three keys on requirements.md, beside the kickoff answers: branch: feat/user-auth pr: 28 delivery: in-progress | in-review | merged | abandoned The vocabulary is closed for the reason a task's flags are — an open one produces three spellings of "done" inside a month, and what is still unfinished is exactly the question a synonym destroys. Absent is the fifth state and needs no name, so the validator grades these only when present and every existing spec keeps passing. `delivery:` rather than `status:`, which already means the approval seal on a plan. - `scc spec track <feature> --here|--branch|--pr|--delivery` records what the caller knows. `scc spec sync` derives what git and the forge know, over every spec, under the same verify-and-roll-back contract as `scc patch`. `scc spec list` and `spec show` carry the record. - Neither guesses. A deleted branch with no PR to ask about is reported undetermined and left as it was: merged and abandoned are indistinguishable once the ref is gone. - Merged is not "is an ancestor of the base" — a branch created ten seconds ago satisfies that, and the first run declared a spec delivered before a line of it existed. It is ahead == 0 with behind > 0, and the fast-forward case no ref can resolve is called not merged: this record exists to surface unfinished work, so the error that leaves a loose end visible is the one to make. - internal/git is the fourth integration package. git and gh together because the question has two halves and no caller should route between them; nothing in it installs and nothing writes, which is what makes running it over a whole workspace safe by construction. - Plans are out for now for a naming reason: `pr:` on a plan already means the delivery shape plan-run asks for at kickoff. **The record carries no attribution.** No Co-Authored-By for an assistant, no session link, no generated-with footer, no naming of a model, vendor, or harness — in a commit message, a PR title or body, or a branch name. The work is the user's: a tool that signs what it did for somebody is claiming a share of it, and the honest signature is the diff. These lines also outlive the session that wrote them, ending up in release notes and every downstream fork. Harness defaults push the other way, so the rule states it and TestNoTemplateShipsAnAttributionFooter keeps any template from modelling what the rule forbids. It binds scc's own history first, recorded in CLAUDE.md. Template versions 20 and 21; delivery.md absorbs both at its 62-line cap by tightening the argument the design doc holds in full.
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.
Two halves of one question: what the record of a delivery says.
The spec records where it is being built
A branch was the one part of this methodology that left no trace in the artifacts. The spec said what the feature does and which boxes were ticked; git said a branch called
feat/user-authhad been sitting unmerged for three weeks. Nothing joined the two, so which of these actually shipped was answerable only by somebody holding both halves — and underautonomy: autothere is nobody holding either.Three keys on
requirements.md, beside the kickoff answers, because that file is already the spec's header:The vocabulary is closed for the same reason a task's flags are: an open one produces three spellings of done inside a month, and "what is still unfinished" is exactly the question a synonym destroys. Absent is the fifth state and needs no name — it is what every spec written before this looks like, which is why the validator grades these only when present.
delivery:rather thanstatus:, which already means the approval seal on a plan.trackrecords what the caller knows;syncderives what git knows.syncwalks every spec, asksgitand — when installed —gh, and writes back under the same verify-and-roll-back contract asscc patch. Neither guesses: a deleted branch with no PR to ask about is reported undetermined and left exactly as it was, because merged and abandoned are indistinguishable once the ref is gone.Two things were wrong in the first cut and the failures were instructive:
mergedis what a merged branch is supposed to look like; warning about it would put a line on every finished spec forever, which is how a report stops being read.New findings:
spec.delivery-invalid,spec.pr-invalid,spec.branch-invalid, andspec.delivery-unstated— a branch or PR recorded with no state is half a record, which is the loose end this exists to surface.internal/gitis the fourth integration package, alongside rtk, headroom and codegraph.gitandghlive together because the question has two halves and no caller should have to route between them. Nothing in it installs and nothing writes — every call is a query, which is what makes running it across a whole workspace safe by construction.Plans are deliberately out for now, for a naming reason rather than a principle:
pr:on a plan already means the delivery shape plan-run asks for at kickoff (per-plan/per-group), so one key would carry two meanings on one file. Plan tracking starts by renaming that answer.The record carries no attribution
Not modesty and not about hiding the tool. A trailer is a claim on authorship, and a tool that signs what it did for somebody is taking a share of something it was hired to produce; the honest signature is the diff, already in the record and already attributable. The practical half matters too — these lines outlive the session, ending up in release notes,
git shortlog, and every downstream fork.Harness defaults push the other way, so
TestNoTemplateShipsAnAttributionFooterkeeps any template from modelling what the rule forbids (Co-Authored-Bywithout a colon is allowed in exactly one place: the sentence forbidding it). It binds scc's own history first — recorded inCLAUDE.md, and this PR is the first one written under it.Budget
Template versions 20 and 21.
delivery.mdabsorbs both changes at its 62-line grandfathered cap: thegit switch -cfenced one-liner goes inline, and §8's argument is tightened to prose the design doc holds in full anyway.plan-runrecords the delivery at step 4 — it is the loop that opens the most branches.Checks
gofmt -lclean ·go vet ./...clean ·go test ./...green ·golangci-lint run→ 0 issues. The git-backed lifecycle test skips where git is not on PATH; the reconcile policy is a pure function and is tested without a repository.