Repository navigation
feat: keep plan, results, and build evidence on the metadata branch; ship the spec with the PR - #398
Merged
danielhanold merged 28 commits intoOct 6, 2026
Conversation
Docket-Plan-Path: docs/superpowers/plans/2026-10-05-keep-plan-results-and-build-evidence-on-the-metadata-branch.md
…read the record's build evidence
pr publish keeps verifying --evidence against the head but weaves only the backlink block into the PR body (assemblePRBody drops its record parameter); an authored build-evidence block is preserved as authored bytes. finalize publish and evidence recertify no longer edit the PR: after the PR reprobe the change record's "## Build evidence" write is the publication (publishResultFromRecord replaces publishResultFromEnsure). Removed finalizePublishEnsurer, mapPublishEnsureFailure, mapRecertifyEnsureFailure, and the reasons body-assembly-failed (publish/recertify), pr-editor-unavailable, pr-edit-contended, and pr-edit-unknown. evidence.recertify is metadata-write only. Test changes: - EvidenceRecertifyEditContended -> RecordContended (the record moved under the write). - EvidenceRecertifyEditFailureThenRetry -> RecordFailureThenRetry (a failed record write, then convergence). - Deleted EvidenceRecertifyEditUnrecognizedDisposition: it only exercised the PR-edit disposition mapping's default arm, which no longer exists. - Deleted the dispositionEnsureGitHub and flakyEnsureGitHub fakes and fakePublishGitHub.lastEnsuredBody (no PR edit left to drive).
…s backlink change.attach-plan now carries the plan Markdown (--markdown <file|->) and, in one metadata transaction, writes docs/superpowers/plans/<file> on the metadata branch behind its freshly rendered backlink (any submitted backlink block is replaced), sets plan: and updated:, and re-renders the artifact block and board. A re-plan at the linked path replaces the content; an identical re-attach declares nothing. New typed refusals: empty-markdown, authored-input-too-large, artifact-path-mismatch (plan: already names another path), and artifact-path-occupied (a file at the path whose backlink targets another change). Malformed backlink markers and placeholder-only slots still refuse. The feature-head, descends-from-base, single-artifact-delta, and plan-path trailer checks are removed with their reasons and helpers. run.verify reads the plan on the metadata tip; status checks the plan on the metadata branch with an integration-branch fallback for records closed before plans moved. attach-results is unchanged until it moves next.
…rs follow change.attach-results now carries the results Markdown (--markdown <file|->) and runs the same metadata transaction as attach-plan: it writes the results file on the metadata branch behind its freshly rendered backlink, sets results: and updated:, and re-renders the artifact block and board in one commit. A later checkpoint at the linked path replaces the content; the feature branch is never read or written, so a checkpoint after the gate leaves the tested head (and its evidence) intact. Checkpoint-phase content validation still refuses raw template scaffolding (results-content-invalid), now before anything is read. The feature-head driver is deleted with everything only it used: --commit, ChangeAttachRequest.Commit, the WorkspaceDeps parameter, readAttachBlob, verifyBacklink, and the commit-not-head, untracked-file, symlinked-plan, missing-backlink, backlink-mismatch, and artifact-unreadable reasons, plus the now-unminted empty-commit finding code. Both CLI verbs share one flag set (--id --revision --path --markdown). mark-implemented (condition 5) and run.verify read results on the pinned metadata tip; a results file present only at the feature head is results-identity-broken. status checks results on the metadata branch with an integration-branch fallback for records closed before results moved. The run-fence ownership fixtures now serve the plan and results on the metadata branch too.
…branch Plan and results live on the metadata branch, so the archive transaction's retargetArtifactBacklinks already repoints every artifact backlink in the one close-out commit. The integration-ref legs are retired: closeoutBacklinkOp and runCloseoutBacklinkLeg (close-out), cleanupBacklinkOp and finalizeCleanupBacklinkRepair (cleanup), sweepAssessBacklinkLeg (sweep), the scoped backlinkArtifactLoader and backlinkLegDetail, backlinkLegRetarget / backlinkLegHasWork, OperationFinalizeCloseoutBacklink, and both final-backlink-pending reason constants. The PR-description backlink leg stays. finalize.cleanup no longer declares the metadata-write effect (it commits nothing). New guard internal/repoguard/integration_push_test.go (TestNoIntegrationPushOutsidePRMerge): every transaction.Request literal under internal/app must target MetadataBranchName, and every direct PushLease/PushCreateLease call must sit in an allowlisted function. Tests deleted, with reasons: - TestIntegrationFinalizeCloseoutBacklinkLegIgnoresUnrelatedCorpusErrors, TestIntegrationFinalizeCloseoutBacklinkPendingFindingNamesTheCause, TestIntegrationFinalizeCleanupBacklinkRepairIgnoresUnrelatedCorpusErrors: they pinned the scoped loader and pending finding of the retired integration-ref legs. - finalize_backlink_loader_test.go: its subject file is deleted. - TestAssessStaleBacklinkLegIsActionable, TestAssessMissingManifestWithStaleBacklinkIsActionable, TestAssessMalformedMarkersAreUnknownNeverNoWork: they assessed the retired sweep integration backlink leg. Converted: setupCloseoutFixture seeds plan/results on the metadata branch with relative backlinks; TestIntegrationFinalizeCloseoutBacklinkLegDocketMode became TestIntegrationFinalizeCloseoutArchiveRetargetsAllArtifactBacklinks (one metadata commit retargets spec/plan/results; origin/main stays the merge commit); matrixCloseout, TestIntegrationFinalizeStateBytePreservation and TestIntegrationFinalizeArchive* read plan/results on docket and assert no integration commit; the clean-tombstone sweep assessment now proves a stale integration-branch plan is no work; TestFinalLifecycleCodeSpellings drops the two retired constants; retired-vocabulary row 57 has no successor.
…nch; the spec copy rides the PR
…ce lives in the record
…h the PR Living docs describe the current layout: plan, results, and build evidence on the metadata branch (evidence in the record's ## Build evidence section), the spec copy as the feature branch's first commit, relative same-branch links converted by repository repair, close-out retargeting every backlink in the archive commit with no integration-branch push. Glossary entries rewritten; the artifact backlink example, the retired `docket artifact` noun, and the stale verify-run alias line are removed. Residual retired-token hits (git grep -F over the whole tree): - Docket-Plan-Path: docs/codex/fixtures/root-entry/certification.md (dated 2026-09-01 certification record, point-in-time); testdata/bash-upgrade tarballs (frozen corpus). - Docket-Results-Path, closeout-backlink, prBodyEvidence, lifecycleBranch, commitPlanFile: no hits outside point-in-time records. - artifact.backlink: internal/repoguard/budgets_test.go re-baseline history comment (historical rationale). - artifact backlink: internal/app/finalize_closeout_integration_test.go comment describing the metadata-branch retarget (current behavior). - final-backlink-pending: retired-vocabulary guard row only. - skip_results_only_delta: the obsolete-key tombstone (config schema, decode, tests), prose-contract absent pins, the upgrade guide's "ignores it, remove it" row, and frozen testdata corpora.
Review finding (important): change_attach.go changeAttachMetadata keyed its idempotency RequestID and digest on (kind, id, path, content) only. The engine's scanForRequest searches the whole metadata ancestry, so attaching X, then Y, then X again replayed the first X receipt and left Y stored while the caller saw applied. Fold the submitted revision into the digest payload and (hashed) into the RequestID: a lost-response retry at the same revision still replays, while earlier bytes at a later revision are a new request. TestIntegrationWorkflowRepoChangeAttachRevertToEarlierContent pins both.
…atch claim refresh Review finding (important): Step 4 refreshed the claim with the pre-dispatch revision after the plan-writer's change.attach-plan had already moved the record, so the refresh came back contended and stopped the build. The parent now verifies the return, re-reads the revision on the re-synced tree, and refreshes with it; the post-build refresh in Step 5 does the same, since a build checkpoint (change.attach-results) also moves the record.
…ture branch Review finding (legacyIntegrationArtifacts): a pre-cutover killed record with plan:/results: set rendered relative metadata-branch links to files that only ever lived on its feature branch, so repository check/repair would rewrite them into dead links. legacyArtifactBranch now keeps a killed record without a "## Build evidence" section on its feature branch, the pre-cutover rendering; a killed record with the section stays relative.
F4: cli.md workspace summary names the commit-spec verb. F5: edge-paths/SKILL.md say pr.publish owns the PR-body back-link and plan/results links blocks; drop the stale skill-side claim. Regenerate embedded twins.
The shared non-JSON file reader always said "reading --record", so a bad --markdown, --evidence, or --request path was reported against a flag the caller never passed. Each caller now hands the reader its own flag name.
Recertify can no longer edit a PR, so the refusal tests' no-PR-edit asserts could never fail. They now assert the record, recertify's only durable write, is unchanged.
danielhanold
deleted the
feat/keep-plan-results-and-build-evidence-on-the-metadata-branch
branch
October 6, 2026 09:57
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.
Moves a change's plan, results, and build evidence off the PR. Plan and results are written to the
docketmetadata branch bychange.attach-plan/change.attach-results(now--markdown); build evidence lives in a## Build evidencesection of the change record, read by the finalize merge gate, clear-block, the rebase no-op skip, andrun.verify. The feature branch's first commit is a spec copy (workspace.commit-spec), so a PR carries the spec plus code. Same-branch links become relative; the post-merge backlink commit tomain,artifact.backlink, theDocket-Plan-Pathtrailer, andfinalize.skip_results_only_deltaare retired. ADR-0141.Cutover: finish every in-progress/implemented change on the current binary before installing this one; then run
docket repository repaironce. This PR itself was built on the previous flow (its plan and results ride this branch, evidence is in this description), as the spec requires.Review (deep tier) — dispositions
workspace commit-speccommand: go run ./cmd/docket development test
result: green
head_sha: a17fd60
ran_at: 2026-10-06T09:49:42Z