Development record
abcd records how each change landed
Summary
Delivers itd-2610301850454860. The implement loop writes the rule a lane was admitted under into history before the merge: Every lane's landing makes its records commit, even one with no record to move, and that commit carries an Admitted-by: trailer naming the drain rule record or the spec or issue the lane was built for, read from a new admitted field the run's state takes at its start. A new read-only verb, abcd landings, then classes every commit on the default branch's first-parent line as person-approved, drain, automatic, or person-push, naming the rule that admitted it, from history first and from the forge only for what history cannot hold, and traces a revert to the landing it undoes. The reader is a core function before it is a verb, because the spot-check (itd-2610301750162657, spc-2610301925429250) draws from it at landing time, inside a landing that has no terminal to print to.
Grounding, read on 30 October 2026:
- The run's state is
State(internal/core/implement/loop/state.go:354), schema version 16 (:227), written once at the start bystart(loop/loop.go:509-541,writeStateatstate.go:1297) and read strictly byReadState(:1001), which refuses a version it does not know (:1105-1108). Version 16 landed on 2026-10-28 (commit be5b5bc05) and the last release is v0.15.1 of 2026-10-17, so no release has written version 16 yet and a field may still join it.State.Issue()(:986) says whether a run is keyed by an issue;State.Specholds the spec a build run builds against;State.Pick(:385) is set only for a picked run. - The drain reads its rule once with
drainrule.Load(loop/drain.go:350), keeps onlyrule.Recordin its own state (:423), builds the lane's options by copying its own and marking themdrain(:1120-1125, the unexportedOptions.drainatloop/loop.go:96), and starts the lane throughstartLane, which isStart(:376,:1155).drainrule.RulecarriesRecord(the ADR id, empty only for the bundled baseline, whichLoadnever returns as a repository's rule) andPath(internal/core/drainrule/drainrule.go:92-110,Baselineat:115,Loadat:164).abcd build <id>callsloop.Start(root, args[0], o)(internal/surface/cli/build.go:236). - The landing's steps are
landStage(loop/land.go:139-177):landPrepare(:215) computes what the landing does and, when it marks no step, closes no spec, and resolves no capture, setsRecordsDonewithout a commit (:254-257);landRecords(:303) settles theAssisted-by:disclosure first (:328-334,composedAssistedByatloop/composed_attribution.go:30for a commit of abcd-computed facts), writes the records, refuses when nothing is staged (:404-407), composes the message fromlandSubject(:134), a prose line, and theDelivers:,Resolves:, andAssisted-by:trailers (:414-420), and commits throughgitutil.LocalGitwith the repository's hooks running (:424).landPush(:494) refuses until a preflight receipt names the head (:510-520). The loop's pull request body (prBody,:665-694) ends with the same trailers. The pick commit is made only whenState.Picknames the lane (loop/lane.go:297), so a drain lane and abuild <id>lane have none. - The merge gate is
DecideMerge(internal/core/landing/facilitator.go:396): The mode is read at the fetched default tip with the machine layer (readFacilitatorAt,landing/config.go:248, throughlayered.Roots.RepoAt,internal/core/layered/layered.go:142-150,readRepoAtat:359);countedApproval(facilitator.go:188) takes the recorded approval first (approvalRecord,:248, underApprovalsRelDir,:54, written byRecordApproval,:264), else the latest review per reviewer that approves the head by someone other than the author with write access, over one page ofmaxReviews(:69,reviewsArgsat:87, a full page counting none);reviewReceipt(landing/review.go:179, underReviewReceiptsRelDir,:24) is a file named by the head. Both stores are found across every worktree git lists (findReceipt,landing/primitives.go:64).mergeGate(:329) arms by its table; itsMergeDecisionis kept nowhere. The loop asks it atloop/land.go:898andabcd landatlanding/land.go:1284. - The forge client the landing uses is
landing.GH(primitives.go:113), bounded byForgeTimeout(:46, two minutes) and a scrubbed environment;GHContext(:126) also honours a caller's context.abcd landalready asks the forge in GraphQL throughgh api graphql(PRStateQuery,landing/land.go:1119,prStateArgsat:1124).internal/core/githubis the other door (Runatgithub.go:183,APIat:166,Timeoutof thirty seconds at:42, output bounded at:48); neither door pages or reads rate-limit headers, and each bounds one page (maxReviews,activityPageatgithub/activity.go:36with apartialflag,maxMergedListedatprimitives.go:197). - The default branch's merges are the queue's merge commits: Over the thirty days to 2026-10-30, 491 first-parent commits on
origin/main, all merges, each with the branch's tip as its second parent and the pull request number in its subject (Merge pull request #N from ...); 199 since v0.15.1. The ruleset mirror sets the queue's method toMERGE(.abcd/work/rulesets/main-protection.json:75-79, read byReadMergeRule,landing/ruleset.go:84,MergeMethodsat:22). Older history holds squash merges, whose subject ends in(#N)and which have one parent. Reverts on the branch carry git's ownThis reverts commit <sha>line (three in the last sixty days). - RS001's revert reading is
revert_pairs(scripts/check-issue-resolution.sh:691-705):git log --no-merges --grep='This reverts commit [0-9a-f]{7,64}', each named commit resolved and held to be an ancestor of the reverting one;withdrawn_by(:706) handles a revert of a revert. The same script's RS004 (:40-69) refuses a commit message that names aniss-N(MENTION_RE,:208) without aResolves:orRefs:line declaring it (DECLARE_RE,:197), and the commit-msg hook runs that message half at every commit (.githooks/commit-msg:33-35) afterabcd lint outbound(:16,:392), which judges session URLs and tool footers (internal/adapter/scanner/outbound.go:28,:145). scripts/check-attribution.shjudges a message for a generated footer (GENERATED_RE,:143), any co-authorship trailer (COAUTHOR_RE,:155), a malformed abcd label (ABCD_RE,:106), and the presence of oneAssisted-by:form (TRAILER_RE:67,NONE_RE:81;check_textat:520). It names no other trailer key, so a lineAdmitted-by: ...is neither refused nor required by it. The loop'sTestTheLandedRangePassesTheAttributionGate(loop/land_attribution_test.go:157) already runs the script over a landed range.- The composed body of
abcd land(landing/prbody.go:60) copies from the branch's commits onlyResolves:,Refs:,Delivers:, andAssisted-by:lines (:44-45,:78-84); a person's branch has noAdmitted-by:to copy, and the loop's body is composed inloop/land.go:665. - A verb lands with its row:
cli.go:409adds the command (newPeersCommand,internal/surface/cli/peers.go:166, is the shape),helpgroups.go:128-175places it in a group or the agents block (TestEveryVisibleVerbHasAGroup,helpgroups_test.go:194),internal/core/surface/sentences.go:398-408holds its one sentence,go generateregenerates the snapshot (surface.go:3,SnapshotPathatinternal/core/surface/snapshot.go:60) and the CLI reference (reference.go:3,docs/reference/cli/commands.md), and the brief's registry (.abcd/development/brief/04-surfaces/README.md:52-54, rows 38 to 40) names its chapter, whose## Sub-verbstablesurface_coveragechecks (39-status.md:11-22,internal/core/lint/subverbs_test.go). Invariant 7 (02-constraints/03-invariants.md:21) names every network act per verb.
Approach
- The run's state names its admission.
StategainsAdmitted *Admitted(json:"admitted,omitempty"), withKind(drainorbuild),Record(the drain rule's ADR id, the spec id, or the issue id), andPath(the rule record's repo-relative path, for a drain's run only). It joins schema version 16, which no release has written.startsets it beforewriteState: The drain passes thedrainrule.Ruleit loaded through a new unexportedOptions.admitted, set besidelane.drain = true(loop/drain.go:1125), so every lane the drain opens carries the rule the drain began under;abcd build <itd-N>andabcd build nexttakebuild <spec id>fromchk.Spec;abcd build <iss-N>takesbuild <iss-N>fromchk.Key. Adrainoption without a rule record (the bundled baseline) is refused at the start, namingdrainrule.Load, so a trailer can never readdrainwith no id. The run record gets one entry at the start,admitted under drain adr-N (path)oradmitted under build spc-N, as the pace and review set get theirs. - Every lane makes its records commit, and the commit carries the trailer.
landPrepareno longer setsRecordsDonewhen the landing has nothing to move (loop/land.go:254-257goes); its note readsrecords only the admission.landRecordsrefuses before it touches the worktree whenc.State.Admittedis nil, naming the field and the fix (start the run again with this abcd; a run begun before it recorded admissions cannot land under it), so no commit is ever made without the trailer. With the field, it appendsAdmitted-by: drain <adr-N>orAdmitted-by: build <spc-N|iss-N>to the trailers afterDelivers:andResolves:and beforeAssisted-by:; when the trailer names an issue the commit'sResolves:lines do not, it also writesRefs: <iss-N>, since RS004's message half (the commit-msg hook) refuses a bare mention. When nothing is staged and the landing had nothing to move, the commit is made with--allow-emptyand the proserecords only the admission; the refusal at:404-407stays for a landing that was to move a record and changed nothing. A record-only commit carriesAssisted-by: abcd:<version>alone (composedAssistedBy), since every word of it is a fact abcd computed; a commit that carries a model's prose keeps the receipts' models as today.lane.HeadSHAbecomes the commit, so the preflight receipt, the push, the review receipt, and the merge all name it, as they name the records commit today. The pull request body (prBody) adds the sameAdmitted-by:line among its trailers, with the sameRefs:rule, so a squash merge that adopts the body keeps the admission in history. The landing's refusals say what they say now; the trailer adds none. - Nothing is added to a person's branch.
abcd land(landing/land.go:252) keeps writing no commit: The gate, the push, and the arming name the head the person made, andLandwrites only the composed body in the local tier (prbody.go).TestLandMovesNoHeadAndWritesNoTrailerasserts the branch tip before and afterLandand reads the message of every commit intracking..headfor anAdmitted-by:line. - The reader is a core package,
internal/core/landings. Its entry isList(ctx, repoRoot, Range, Options) (Listing, error), andTrace(ctx, repoRoot, sha, Options) (Trace, error)for one commit.RangeisFromandTo(full object names,Tothe default branch's tip as last fetched,refs/remotes/origin/<default>fromgitutil.DefaultRef), resolved by the verb from--since(approach 8) and by the spot-check from its window'sfrom_commit..to_commit.OptionscarriesForge landing.ForgeCall(nil islanding.GHContextbound toctx) andWorktrees(nil lists them asfindReceiptdoes). The package exports the trailer's grammar,ParseAdmitted(message) (Admitted, bool), which the loop uses to compose and tests use to read, so there is one spelling.landingexports two seams it already has unexported:ApprovalRecord(repoRoot, sha)andCommittedMode(repoRoot, commit) (mode string, found bool, err error), which reads.abcd/config.jsonas the commit holds it (git show <commit>:.abcd/config.json, bounded asreadRepoAtbounds it) and judgesfacilitator.modewithcheckMode(config.go:189), the repository layer alone and never the machine layer, since the listing reads a past commit and the merge gate's machine layer is gone with the moment. A mode the file does not set ishuman, the bundled default (config.go:237).Listfetches nothing and writes only its cache (approach 6): The spot-check calls it right after its own fetch, and the verb says which tip it read. - One
Rowper first-parent commit, newest first, and four classes decided in order. Onegit log --first-parent --format=%H%x1f%P%x1f%ct%x1f%cn%x1f%s%x1f%B%x1e From..Togives every row; onegit log --format=%H%x1f%P%x1f%B%x1e From..Togives every commit the range reaches, second parents included, from which the rows' branches are assigned in memory (each commit belongs to the first-parent row whose second-parent walk first reaches it, stopping at the first-parent line and at commits already assigned). A row holdsCommit,When,PR(from the subject'sMerge pull request #Nor trailing(#N)),MergedHead(the second parent, or the forge'sheadRefOidfor a one-parent row that names a pull request),Class,Rule{Kind, ID, Path},Lane(drain,build,unknown, or empty for a person's push),Approval{Seen, By, At, Source}withSourceone offorge,local tier,none seen,forge unread,Mode(humanorauto, withmodelesswhen the first parent holds no.abcd/config.json),Resolves,Delivers,AssistedBy(from the branch's commits' trailers, once each),Unattended bool, andReverted *Revert. The classes, in this order:person-push: A one-parent first-parent commit whose subject names no pull request;Committerfrom%cn, no rule, no lane kind.person-approved:ApprovalRecord(MergedHead)found in a worktree of the listing checkout (Source: local tier, and the row says it was read from this checkout's local tier); else the forge's latest submitted review per reviewer, notPENDINGand notDISMISSED, whose state isAPPROVED, whose commit isMergedHead, and whose author is not the pull request's author, read ascountedApprovalreads a page but without the permission read, so the forge is asked once per pull request (Source: forge,Bythe login,Atthe review's time); elseCommittedMode(first parent)ishuman(Source: none seen, rulefacilitator.mode: human). The lane kind is shown whatever it is (decision 8).drain: Underauto, the branch carriesAdmitted-by: drain <id>; rule by id and path.automatic: Underauto, everything else; rulefacilitator.mode: autoas.abcd/config.jsonheld it at the first parent, by its path and commit. The row names the mode's requirement (a review receipt naming the head), never a receipt, which decision 6 says is not recoverable.Unattendedis true fordrain, forautomatic, and for any row underautowhose lane kind isunknownor whose approval isforge unread(decision 9); never forperson-approvedorperson-push. A landing from before this ships has no trailer, so its lane kind isunknownand its class comes from the approvals and the mode alone; nothing is rewritten.
- The forge, asked at most once per pull request, through the landing's own client. For every row that names a pull request, one GraphQL document per batch of up to twenty pull requests, aliased nodes of
pullRequest(number:N){number author{login} headRefOid mergedAt body mergeCommit{oid} reviews(last:100){totalCount nodes{author{login} state commit{oid} submittedAt}} commits(first:100){totalCount nodes{commit{oid message}}}}, run asgh api graphqlthroughlanding.GHContext(ctx, ...)(each call withinForgeTimeout), pinned ininternal/ghcontractbesidePRStateQuery. The answer gives the author and reviews (approach 5), the body (approach 7), and the commits, which are read only for a one-parent row (a squash or rebase merge): its lane kind, rule, and trailers come from those commits' messages, and withtotalCountabove the page, or the forge unreachable, the lane kind isunknownand the row counts as unattended. A reviews page withtotalCountabove 100 counts no approval for that row, asmaxReviewsdoes. A forge that cannot be asked (no client, a timeout, a rate-limit refusal, an answer that does not parse, or errors in the document) leaves class and rule to history, sets every unanswered row's approval toforge unread, classes no rowperson-approvedby a forge review, and puts the reason onListing.ForgeUnread; the verb prints it once, after the rows. Answers are cached per pull request in.abcd/.work.local/landings/pr-<N>.jsonkeyed by the row's commit, so a re-run asks only about pull requests it has not read; an unread answer is never cached, and the cache holds the login a row prints, which is the local tier and never a committed file.TestNoLoginInACommittedFilelands a fixture with a distinctive login and asserts no tracked file carries it. - The revert trace reads git's own words over the whole range. From the second
git logof approach 5, every commit whose body carries^This reverts commit [0-9a-f]{7,64}(the linerevert_pairsreads) names a commit; the named commit is resolved to a full name, required to be an ancestor of the reverting one, and followed to its row through the assignment of approach 5 (a first-parent commit is its own row). The row is markedReverted{By, ByRow, Kind: "revert"}; a revert of a revert marks the reverting commit's row the same way, aswithdrawn_byreinstates. A one-parent row whose pull request body saysReverts #NorReverts <owner>/<repo>#N(the forge's own revert line, read from the cached answer) marks the row of pull request N withKind: "forge". A row whose subject is git'sRevert "<subject>"with neither line isKind: "untraceable", and it marks nothing.Trace(sha)resolvesshaas a prefix, saysnot on the default branchwhen it is not reachable fromTo, and otherwise returns the row that brought it onto the default branch (following its first-parent assignment back however far, so a positional trace is not bounded by--since), with the row's class and rule, and, for a reverting commit, the row it reverts as well.--revertedlists the marked rows grouped by rule (drain adr-N,facilitator.mode: auto,facilitator.mode: human,person-push), each group with a count, anduntraceablereverts in a group of their own. - The verb,
abcd landings. A new top-level verb, a person's verb in the records group besidestatus:landpushes and arms and should not also be the reader's verb, andstatuslists announcements that lapse within the hour (decision 10). Flags:--since <tag|date>(a tag, or a dateYYYY-MM-DDtaken as the first first-parent commit at or after it; the default is the last release tag reachable from the default branch,git describe --tags --match 'v*' --abbrev=0, and with no such tag the verb refuses naming the flag),--unattended,--reverted,--json, and one positional commit forTrace. The text render prints one line per row,<short sha> #<pr> <class> <rule> lane <kind> approval <source[: by, at]> <ids>, then the forge note and the tip it read;--jsonprintsListingwith stable keys (tip,from,to,since,rows[],forge_unread), the same rows as the text.--unattendedkeeps the rows withUnattendedset;--revertedrenders approach 7's groups. It lands with its sentence insentences.go("abcd landings": "List how each change landed on the default branch, with the rule that admitted it: Writes only its forge cache in the local tier; refuses no default branch or no range."), its row inhelpgroups.go(groupRecords), its pagecommands/landings.md(block: people), row 41 in04-surfaces/README.mdwith chapter04-surfaces/41-landings.mdand its## Sub-verbstable, the regenerated snapshot and CLI reference, the new package ininternal/README.md, and invariant 7's line forlandings(one read of the forge per pull request, no fetch, no push).commands/implement.md,04-surfaces/34-build.md, and35-drain.mdgain the trailer's line where they describe the records commit. - What the spot-check reads from this. spc-2610301925429250 relies on exactly:
Listoverfrom_commit..to_commitwith rows classeddrainandautomaticandUnattendedcovering every row the evidence cannot place with a person;Approval.Source == "forge unread"so the draw can refuse rather than guess;Rule{Kind, ID, Path},When, andPRfor its card;Tracefor a card'snow; and actxthe draw bounds. All of them are exported here and none is behind the verb. The draw's bound is its own:Listhonoursctx, and each forge batch is bounded byForgeTimeout, so a range of many unread pull requests can outlast oneForgeTimeout; the cache makes the second read of a window cheap, and the consumer should pass the deadline it can afford.
How each criterion is met
- Drain lane's records commit carries
Admitted-by: drain <rule record id>and passes both gates. Approaches 1 and 2. Tests:TestDrainLaneCommitsItsRule(a fixture drain over a repository with a drain rule ADR; the lane's records commit message holds the trailer besideResolves:andAssisted-by:),TestTheLandedRangePassesTheAttributionGateextended with the trailer,TestTheRecordsCommitPassesTheCommitMsgHook(the repository's hook installed in the fixture; the commit is made). - Build lane carries
build <spec id>;abcd build <iss-N>carriesbuild <iss-N>. Approaches 1 and 2. Test:TestBuildLaneCommitsItsSpecOrIssue(an intent-keyed run and an issue-keyed run). - A lane with nothing to record still commits, changing no file, pushed head is that commit. Approach 2. Test:
TestRecordOnlyLaneStillCommits(an empty commit on the branch,Landing.RecordsandPushedequal to it,git diff-treeof the commit empty). - State names
admittedat the start; a state without it refuses the records step and makes no commit. Approach 1 and 2. Tests:TestStartRecordsAdmission(drain with rule path, build with spec, build with issue, picked run),TestRecordsStepRefusesAStateWithoutAdmission(a version-16 state file with the field removed; the refusal namesadmitted, the branch tip is unmoved). - A person's branch gets no commit and no trailer. Approach 3. Test:
TestLandMovesNoHeadAndWritesNoTrailer. - One row per first-parent commit, newest first, with commit, pull request, class, rule, lane kind, approval, issues, and intents. Approaches 4 to 6, 8. Tests:
TestListsEveryFirstParentCommitNewestFirst(a fixture branch of merges, a squash, and a direct push),TestRowCarriesResolvesAndDelivers,TestLandingsText. - Forge review by someone other than the author, not dismissed, of the merged head:
person-approved, review and time named, lane kind shown, login printed and in no committed file. Approaches 5 and 6. Tests:TestPersonApprovedByForgeReview(an approval of an earlier commit, a dismissed approval, and the author's own approval each count nothing),TestApprovalWinsOverTheLane(a drain lane with a forge approval isperson-approved, lanedrain),TestNoLoginInACommittedFile. - Recorded approval in a worktree of the listing checkout:
person-approved, source named. Approaches 4 and 5. Test:TestPersonApprovedByRecordedApproval(the approval written in a sibling worktree's local tier). - No approval seen and committed
humanmode:person-approvedby the mode, approvalnone seen. Approaches 4 and 5. Test:TestHumanModeIsAPersonsMerge(the mode read from the first parent's.abcd/config.json, not the working tree and not the machine layer). - Under
auto, no approval,Admitted-by: drain: classdrain, rule by id and path. Approach 5. Test:TestDrainUnderAuto. - Under
auto, no approval, no drain trailer:automatic, rulefacilitator.mode: autoat the first parent. Approach 5. Test:TestAutomaticUnderAuto(abuildlane and a trailer-less branch both). - A one-parent commit naming no pull request:
person-push, committer from git. Approach 5. Test:TestDirectPushIsAPersons. - Squash or rebase: commits and trailers from the forge; forge unreachable gives lane
unknownand unattended. Approach 6. Tests:TestSquashReadsCommitsFromTheForge,TestSquashWithForgeUnreadIsUnknownAndUnattended. --unattendedlistsdrain,automatic, and every row the evidence cannot place. Approaches 5 and 8. Test:TestUnattendedLeavesNoUnplacedRowOut(laneunknownunderauto, approvalforge unreadunderauto, both listed;person-approvedandperson-pushnot).abcd landings <sha>for a reverted or reverting commit prints the row that brought it, or says it is not on the default branch. Approach 7. Tests:TestTraceThroughGitsOwnWords(a revert on a merged branch of a commit on another merged branch),TestRevertOfARevert,TestTraceNotOnTheDefaultBranch.- A squashed revert matched by
Reverts #N; neither line isuntraceable, counted in its own group. Approach 7. Tests:TestSquashedRevertByForgeLine,TestUntraceableRevertHasItsOwnGroup. --revertedmarks each row with the reverting commit and groups by rule with counts. Approach 7. Test:TestRevertedGroupsByRule.- Forge unreachable: class and rule from history, approval
forge unread, no forge-reviewperson-approved, the reason said. Approach 6. Test:TestForgeUnreachableReadsHistoryAlone(a failing fake forge; the note printed once). --since <tag or date>, default the last release tag. Approach 8. Tests:TestSinceTag,TestSinceDate,TestDefaultRangeIsTheLastReleaseTag,TestNoTagAndNoSinceRefuses.- A landing from before this shipped: lane
unknown, classed from approvals and mode, no history rewritten. Approach 5. Test:TestPreShipLandingReadsUnknown(the fixture's history hashed before and after the listing). --jsonprints the same rows with stable keys; nothing written outside the local tier. Approaches 6 and 8. Tests:TestLandingsJSONKeys,TestLandingsWritesOnlyInTheLocalTier(the tree hashed before and after, the cache under.abcd/.work.local/landings/the only new path),TestLandingsFetchesNothing(the fixture'soriginis unreachable and the verb still lists).
Out of scope, recorded elsewhere: Freezing a cycle's rows at launch ship, and the drain's hand-backs and the facilitator's own decisions (both named out of scope by the intent; the spot-check records the latter itself, spc-2610301925429250 approach 2); naming the reviewers per change (itd-2610240922461281); the merge gate's table (itd-2610150602547271, shipped, read and not changed); backfilling trailers onto earlier landings (decision 13); whether a person's own branch merged under auto with no approval seen counts as unattended (decision 16, provisional, reversed by one line in approach 5's Unattended rule); reading the forge's permission per reviewer, which the gate does and the listing does not, so that one ask per pull request holds.
Footprint
- packages: internal/core/implement/loop/state.go, internal/core/implement/loop/loop.go, internal/core/implement/loop/drain.go, internal/core/implement/loop/land.go, internal/core/landing/facilitator.go, internal/core/landing/config.go, internal/core/landings/admitted.go, internal/core/landings/landings.go, internal/core/landings/forge.go, internal/core/landings/revert.go, internal/core/landings/since.go, internal/ghcontract, internal/surface/cli/landings.go, internal/surface/cli/cli.go, internal/surface/cli/helpgroups.go, internal/core/surface/sentences.go, .abcd/development/release/surface.json, docs/reference/cli/commands.md, commands/landings.md, commands/implement.md, internal/README.md, .abcd/development/brief/04-surfaces/README.md, .abcd/development/brief/04-surfaces/41-landings.md, .abcd/development/brief/04-surfaces/34-build.md, .abcd/development/brief/04-surfaces/35-drain.md, .abcd/development/brief/02-constraints/03-invariants.md
- tests: internal/core/implement/loop/land_admitted_test.go, internal/core/implement/loop/state_admitted_test.go, internal/core/implement/loop/drain_admitted_test.go, internal/core/implement/loop/land_attribution_test.go, internal/core/landing/land_test.go, internal/core/landings/admitted_test.go, internal/core/landings/classes_test.go, internal/core/landings/forge_test.go, internal/core/landings/revert_test.go, internal/core/landings/since_test.go, internal/surface/cli/landings_surface_test.go
Steps
- The admission in the run's state and the
Admitted-by:trailer on every lane's records commit- packages: internal/core/implement/loop/state.go, internal/core/implement/loop/loop.go, internal/core/implement/loop/drain.go, internal/core/implement/loop/land.go, internal/core/landings/admitted.go, commands/implement.md, .abcd/development/brief/04-surfaces/34-build.md, .abcd/development/brief/04-surfaces/35-drain.md
- tests: internal/core/implement/loop/land_admitted_test.go, internal/core/implement/loop/state_admitted_test.go, internal/core/implement/loop/drain_admitted_test.go, internal/core/implement/loop/land_attribution_test.go, internal/core/landing/land_test.go, internal/core/landings/admitted_test.go
- The reader: rows, the four classes, the forge read with its cache, and the range
- needs: 1
- packages: internal/core/landings/landings.go, internal/core/landings/forge.go, internal/core/landings/since.go, internal/core/landing/facilitator.go, internal/core/landing/config.go, internal/ghcontract
- tests: internal/core/landings/classes_test.go, internal/core/landings/forge_test.go, internal/core/landings/since_test.go
- The revert trace, the positional trace, and the reverted groups
- needs: 2
- packages: internal/core/landings/revert.go, internal/core/landings/landings.go
- tests: internal/core/landings/revert_test.go
- The verb
abcd landingswith its page, brief row and chapter, sentence, snapshot, and invariant line- needs: 3
- packages: internal/surface/cli/landings.go, internal/surface/cli/cli.go, internal/surface/cli/helpgroups.go, internal/core/surface/sentences.go, .abcd/development/release/surface.json, docs/reference/cli/commands.md, commands/landings.md, internal/README.md, .abcd/development/brief/04-surfaces/README.md, .abcd/development/brief/04-surfaces/41-landings.md, .abcd/development/brief/02-constraints/03-invariants.md
- tests: internal/surface/cli/landings_surface_test.go
Frontmatter
| id | spc-2610301950480609 |
|---|---|
| type | spec |
| lifecycle | open |
.abcd/development/specs/open/spc-2610301950480609-abcd-writes-down-how-each-change-landed.md
open on GitHub ↗ · commit history ↗
References1
- itd-2610301850454860abcd records how each change landedimplements
mentions4
- itd-2610150602547271The facilitator's mode gates the merge
- itd-2610240922461281The review set is a setting, in model classes
- itd-2610301750162657abcd's unattended work is spot-checked against specs and intents
- spc-2610301925429250abcd's unattended work is spot-checked against specs and intents