Repository navigation
Conversation
…fier is allowed The maintainer's ruling of 2026-10-27, which #169's gate implements, reverses the commit-message half of ADR 0033's amendment of 2026-10-02. A reversal is a change of meaning, so under ADR 0068 point 2 it is a supersession: ADR 0241 supersedes that one ruling, and ModelNamedInTheRecordNotTheCommit moves to 0241's set under its key, filed unaccepted (ADR 0066). 0033's Status names the supersession, and AGENTS.md (Every commit, Never) and CONTRIBUTING.md state the ruling. The record still names the tool and the model exactly. Refs #257 Refs #169 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
A section after Every commit: work starts from an issue, decisions and blockers go on it when they arise, found work is filed at once, the pull request lists every issue it touches, closings are checked after landing, and abandoned work is closed as not planned. As the prompt's note of 2026-11-10 asks, "the session" in Landing and After landing is whichever session lands: the delegate lands and checks (ADR 0239), and a cloud session posts its head, lists the issues and asks. Refs #257 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The prompts, the plan's correction from an amendment to ADR 0241's supersession, what changed and what was found (#258). The model is left for the maintainer to fill in, as ADR 0033 provides. Closes #257 Refs #169 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…in moves At both steps land.cs lists every issue a Closes, Fixes or Resolves trailer line in main..head closes, with its title, recognising a trailer as eng/issue-refs.cs does. A pull request's Completes: line is required: missing, malformed, or naming an issue no pushed trailer closes, the landing is refused, and a body it cannot read is refused too rather than skipped. A release descriptor's trailer is a commit's trailer, so it counts. After --main moves main, an issue a pushed trailer names that is still open is printed with its commit and the exit is 1; GitHub unread is 2. It closes nothing itself. Nine fixtures under tests/fixtures/land/, run by eng/ci.cs's land-fixtures job. Refs #209 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The template opens with `Completes: none` and says what the line is and that it is not a closing keyword (#108). AGENTS.md's Landing and After landing bullets name the line, land.cs's refusal and its check after main moves, so the rule and the script say the same thing. Refs #209 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…ogether Under ADR 0224 point 2 the SBOMs are created at the descriptor's date, so the two move together. --sbom runs eng/sbom.cs created at the current UTC day (or --today), replaces the sbom: block with its sbom.txt and sets date: to that day in one edit, then regenerates CHANGELOG.md. --from takes SBOMs already written and refuses them unless each was created on that day; --out says where eng/sbom.cs writes. A tagged version and a descriptor with no sbom: block are refused. --draft points at it. Gates: four fixtures under tests/fixtures/release-sbom/, run by eng/ci.cs's release-sbom-fixtures job, and a ci.yml step that rewrites the newest format-2 descriptor, renamed and backdated, in a scratch directory and requires every SBOM created at the new date and eng/sbom.cs --descriptor to match. Refs #248 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…fore landing At both steps, each release descriptor the head adds or changes is judged against the landing day (UTC): a date: more than three days earlier, or none, is refused, printing the release.cs --sbom command that writes the digests and the date again. Three fixtures join tests/fixtures/land/: four days refused, three days passing, no date refused. Refs #248 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
docs/releases.md rule 3, amended 2026-11-10 with the old text struck and kept, and rule 11's "written, not typed" naming release.cs --sbom. ADR 0102 gets a dated amendment, add-only, saying the same, since rule 3 restates its line on date; no ruling changes, and ADR 0224 is untouched. AGENTS.md's close-out names the command and land.cs's refusal. Refs #248 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…s its digests Closes #248 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The three pull requests and their order, ADR 0241 and ADR 0102's amendment, the issues opened, closed and touched, the fixture counts, the questions for the maintainer, and #258 deferred. Refs #257 Refs #209 Refs #248 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Refs #209 Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Refs #248 Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The maintainer's decision on #230 (accepted as written on 2026-11-06), with his review of 2026-11-11 folded in: the four open questions settled (a reserved header byte as the unstable-build marker, stable tags cut by a workflow on request, packages and SBOMs only, the chain# namespace) and seven additions (landing trains, a pinned gate, bounded trial merges, stable implies accepted, no squash for chain branches, ADR numbers at landing as a step of its own, chain branches opt-in). Each is marked as settled in review, and a table lists every difference from the issue's text. Thirteen keys, filed unaccepted (ADR 0066). Dated amendments to 0088 (main moves by fast-forward, a merge commit made on a branch counts, and a train is one checked head) and to 0102 (chain builds are outside a release's scope, and the release workflow refuses chain/*). Numbered 0243: open pull requests hold 0240, 0241 (twice, #278) and 0242. Refs #277 Closes #230 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Refs #230 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
`dotnet run eng/land.cs -- --train N1 N2 ...` merges the members' heads onto main in the order given, each by `git merge-tree --write-tree` and `git commit-tree`, in commits carrying `Landing-only: merge`, dated at the newest commit they join so that the same members on the same main give the same head. It pushes the head to land/train-N1-N2-..., or to land/release-<version> when the last member carries the descriptor. Refused before anything is built: fewer than two members; a member whose head has no approval for its exact sha, or is not green on its own (every check ruleset 1 requires); a member's Completes: line unmet by its own commits; two descriptors, or one not last; a descriptor dated over three days before landing. A conflict refuses the train and prints the train without the member at fault. `--main` verifies land/<name> is a train onto main of exactly the members' current heads, each merge reproducible, and fast-forwards main; when refused it prints the train without its last member. The closing check runs over every member. Ten train fixtures, built for real in a scratch bare repository, run by the land-fixtures job: 22 cases, 0 judged wrong. ADR 0243 point 10, LandingTrains. Refs #277 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
On a land/ push whose head is not an approved pull request's head, agent review now admits a train: a head whose first-parent line down to main is only two-parent commits carrying `Landing-only: merge`, each one's tree the `git merge-tree` of its parents, and each one's second parent an approved pull request's head by the same check-run test as before; two or more of them. The approvals stay the members' own, and a merge resolved or edited by hand fails. The judge reads the pushed history with git, so on a push the workflow checks main out with its whole history (fetch-depth 0): data, never checked out, built or run. The tamper test builds a train in a scratch repository and proves four cases: approved members pass; a member that is no approved head, a merge edited by hand, and a merge without the trailer each fail. This takes effect once it is on main, because the judge is main's copy. ADR 0243 point 10, LandingTrains. Refs #277 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
AGENTS.md's landing section and commands say how several approved heads land as one train and what refuses one; the Landing and After landing bullets say the closing checks run per member. docs/releases.md §3 says a release rides in a train as its last member, at most one per train, and that the head guard holds for a train's head. Refs #277 Closes #277 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Refs #277 Refs #230 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…nder The maintainer's review of #281, 2026-11-11: land.cs and agent review run git merge-tree under the same settings. Attributes come from the train so far, never from a working tree, with the global and system files off; renames are fixed; a repository-local info/attributes refuses the train. A tree mismatch from a different git refuses the train too. `git merge-tree` reads the working tree's .gitattributes: a merge=union attribute there turned a conflict into a clean merge in a test, so the lander's checkout and the judge's could otherwise disagree. Refs #230 Refs #277 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Brings ADR 0243's pinned merge settings, which this branch implements. Refs #277 Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…amper cases land.cs (Trains.MergeTree) and agent review (PinnedMergeTree) run git merge-tree under the same settings, stated once in each: attributes from the train so far (--attr-source of the first parent), never a working tree, with the global and system attribute files off; renames on, directory renames off, rename limits fixed. A repository-local info/attributes refuses the train in both, because no option switches it off. A tree mismatch says the train may have been built by a different git, and to build it again. Without the pin, git merge-tree read the checkout's .gitattributes: a merge=union there turned a conflict into a clean merge. The tamper test gains two cases, a commit between the merges on the first-parent line and a train built on a main that has since moved, and every train failure case now checks its reason. land-fixtures gains three: attributes read from the train's tree, info/attributes refused, and a failed two-member train printing the plain landing command for the one left (the maintainer's ruling on #277). 25 cases, 0 judged wrong. ADR 0243 point 10, LandingTrains. Refs #277 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
What the tamper cases coverThe four train cases in the first head (
Neither of your two cases was among them, so both are added at
Every failure case now also requires its own reason in the judge's output, so a case cannot pass by failing for something else. All six hold under main's copy. Also in
New head: The full Generated by Claude Code |
|
Completes: #277
What this changes, and why
Step 1 of the chain-builds work: ADR 0243 point 10,
LandingTrains. It is stacked on #280 (step 0, the ADR), which stacks on #261 → #260 → #259. Its own commits are the last four:af72d1d,12cc6c1,a0375e0and the record.Today each landing costs one full CI run and moves
mainunder every other pull request. A train lands several approved heads after one run.eng/land.cs -- --train N1 N2 …approvefor its exact sha. A single landing only warns; a train refuses, because its verdict rests on each member's own;Completes:line is unmet by its own commits (land.cs: list the issues a landing closes, and refuse a PR whose declared issue has no closing trailer #209, per member);git merge-tree --write-treeandgit commit-tree, ontomain, in the order given. Each merge carriesLanding-only: mergeand is dated at the newest commit it joins, so building twice gives the same head. A conflict refuses the train and prints the train without the member at fault.land/train-N1-N2-…, or toland/release-<version>when the last member carries the descriptor, so the release dry run still runs.--mainverifiesland/<name>before it moves anything: the first-parent line down tomain, each merge's trailer and tree, and the second parents equal to the members' current heads. Then it fast-forwardsmainand checks every closing issue is closed. When the push tomainis refused, it prints the train without its last member.--delegated-by <who>adds ADR 0239 point 4's trailer to the merges.eng/agent-review.csadmits a train on aland/push, by the same rule in main's own copy. Every merge's second parent must be an approved pull request's head, by the existing check-run test. On a push, the workflow checks out main with its whole history (fetch-depth: 0), so that git can read the pushed merges as data. This only takes effect once it is onmain.AGENTS.md's landing section, Commands, and the Landing / After landing bullets.docs/releases.md§3: a release rides last in a train, and the head guard holds for a train's head.The release workflow,
dco,issue-refsandrelease-pendingneed no change. They skip merges, or readagent review's run.What was measured
land.cs --fixtures tests/fixtures/land: 22 cases, 0 judged wrong. There were 12 before. The ten new train cases are built for real, in a scratch bare repository.pass-train case copied asfail-gave23 cases, 2 judged wrong, exit 1.agent-review-tamper: every part holds, including four new train cases:land.cs -- --train 266 265 --print, refused both members, each for no approval of its head, checks still running, and noCompletes:line.licence-headers,land,issue-refsanddcopass. The full test pipeline is left to CI.What was found
agent reviewwithout the judge's change. It admitted aland/head only when the head is an approved pull request's head. This was in the plan on Landing trains: several approved heads land in one run #277.agent reviewrun, and the land push now posts that run on a train's head.What is left
--trainis refused, with a pointer toland.cs -- N. Say if you want it to fall through to a plain landing instead.Head:
440a0cf82bba.Checklist
Refs #277on each commit, andCloses #277on the docs commit.docs/releases.md§3.eng/ci.csrun; tamper cases.docs/traceability/2026-11-11-issue-277-landing-trains.md, plus the session close-outdocs/sessions/2026-11-chain-builds.md.dotnet run eng/ci.cspasses locally: only the process gates and fixtures were run.🤖 Generated with Claude Code
https://claude.ai/code/session_01NbWSYNzDrbT3ENstGnmH3N