34 KiB
Audit remediation implementation plan
Objective and baseline
Implement the accepted target in audit.md from baseline b5b3f09.
The eleven audit reports supply evidence and reproduction details;
the target document owns the accepted outcomes and policy choices. This plan
owns execution order, concrete implementation choices, and completion evidence.
Follow Stage 1 through Stage 19 in order as one end-to-end sprint. Stages separate work into units suitable for a Luna coding agent. Intermediate stages may leave related code or tests uncompilable; complete the dependencies before evaluating the final implementation. Run focused checks when the affected packages are ready, and reserve the complete verification pass for Stage 19. Proceed through the sprint without intermediate external actions, pilot integrations, releases, or human review gates.
This sprint implements the selected repairs and internal maintenance. A11 and A17 deliver local assessment evidence while their production changes remain deferred. New JSON limits, exclusion indexing, public configuration, broader concurrent-use contracts, and alternative approaches are future decisions. The public module path, Go minimum, facade types, receipt schema, and source publication completion point keep their current contracts.
Read development.md and the applicable policies before working. Preserve unrelated changes. Use existing fixture helpers, local Git remotes, and local HTTP servers. Keep synthetic module-proxy tests in test-owned module caches. All default tests remain offline and credential-independent.
Completion tracking
Update this table with the completed work and relevant check results as the sprint proceeds. A completed assessment in Stage 18 leaves the corresponding production change explicitly deferred. Commit completed nonempty units under the agent policy; an intermediate compilation dependency is recorded accurately.
| Stage | Work items | Status |
|---|---|---|
| 1 | A01; publication assertion portion of A19 | Complete — regression failed before the fix and passed afterward; focused publication and reconciliation tests passed. |
| 2 | A02, A12: common Git mechanics | Complete — focused Git, candidate, identity, and public build/publication/delivery tests passed; A02 regression evidence follows in Stage 3. |
| 3 | A02: source identity regression evidence | Complete — commit, tree, and blob replacement regressions and public publication, build, and delivery cases passed. |
| 4 | A03: buffered command teardown | Complete — inherited-pipe, cancellation, healthy-command, native build, and publication recovery checks passed. |
| 5 | A03, A18: piped lifetime and queued cancellation | Complete — process and Git lifecycle tests passed under the race detector; public preparation cancellation passed. |
| 6 | A04 | Pending |
| 7 | A05 | Pending |
| 8 | A06, A14 | Pending |
| 9 | A16 | Pending |
| 10 | A07: allocation and temporary metadata | Pending |
| 11 | A07: build and delivery outcomes | Pending |
| 12 | A08 | Pending |
| 13 | A09 | Pending |
| 14 | A10 | Pending |
| 15 | A13 | Pending |
| 16 | A15 | Pending |
| 17 | Remaining A19, A20 | Pending |
| 18 | A11, A17: assessment only | Pending |
| 19 | Integrated verification and current documentation | Pending |
Stage 1: Correct the owned tag push
Owners: internal/git/tag.go and publication tests. Target: A01 and the publication assertion portion of A19.
- Add
--recurse-submodules=notoEndpoint.PushTag. Retain its captured object-to-exact-tag refspec,--no-follow-tags, scoped endpoint, and non-forcing push behavior. - Extend the real local-bare-remote publication fixture with
push.recurseSubmodules=only. Set it after fixture setup has publishedmain. A successful publicPublishmust leave the captured annotated object at the exact remote ref, with the intended peeled commit and note. - Remove the ordinary success test's assertion of exactly three queries. Keep its exact remote object/message and unrelated-ref assertions. Retain the documented single authoritative reconciliation after a failed push.
Evidence: the new regression fails on the baseline and passes with the push option. Existing rejected-push, conflict, and unknown-result cases retain their outcomes. This stage adds no successful-push read-back operation.
Stage 2: Establish shared original-object Git observations
Owners: internal/git, candidate, build, and committed identity. Targets: the mechanics of A02 and A12.
- Make ReleaseKit-owned Git subprocesses use
GIT_NO_REPLACE_OBJECTS=1through per-command environment overlays. Cover the Git command runner, local-object reader, batch-reader startup, discovery/preparation commands, and remaining direct candidate Git commands. Preserve local-only object reads' lazy-fetch/transport controls and network-capable preparation. Apply the override to owned Git children; preserve the existing environments of application Go tests, product checks, and unrelated caller operations. - Reuse
git.CaptureHeadand add a small repository-wide worktree-status observation ininternal/git. Have candidate state inspection, build eligibility inspection, and tagged-source inspection use these primitives. Keep branch and tag observations explicit at their current owners. - Remove build's independent
gitCommitandcleanSourceexecution paths. Preserve its initial/final observation timing, captured commit, dirty-build success behavior,SourceVerifiedcalculation, and contextual causes. - Keep candidate checks requiring clean
main, and delivery requiring the selected tag and clean checkout. Shared observation helpers return facts; they do not impose those caller policies or combine the observations into a new release-state framework. - Leave the unused
InspectLocalTaghelper unused for removal in Stage 17. Preserve the live candidate guard's exact captured-object/type checks.
Evidence: existing dirty-source, changed-HEAD, sparse-checkout, nested-module, Git failure, and source-cancellation cases still express their distinct contracts. Stage 3 supplies the replacement-object regressions before A02 is marked complete.
Stage 3: Prove validated and published source identity
Owners: public publication/build/delivery tests and existing Git/tree fixtures. Target: A02, including the missing regression coverage in testing audit §1.
- Use a real candidate and bare authoritative remote at original commit A. Create a local replacement B with different source and note bytes. Include a case where A fails compilation while B compiles. Materialize the replaced checkout using ordinary fixture Git, then invoke the public release path.
- Assert that a replacement-derived worktree cannot pass candidate validation and publish A as validated source. Compare actual bytes or the contextual rejection, rather than only commit IDs. Also verify that a worktree matching original objects can release normally with unrelated replacement refs.
- Cover original committed reads for commit, tree, and blob replacements at the Git/identity/tree boundary. Reuse one public fixture to show this behavior reaches publication and one existing tagged-delivery fixture to prove the committed note remains the original note. Avoid a module/layout cross-product.
- Retain dirty working-tree
Buildsupport: replacement-derived dirty bytes may compile, but their result is ineligible as clean binary delivery source. Keep ordinary partial build facts and inspection causes.
Evidence: original committed identity/note reads and the publication outcome agree. Do not alter refs, disable unrelated caller configuration globally, or add a repository-wide prohibition on replacement refs.
Stage 4: Bound buffered subprocess I/O teardown
Owners: internal/process/process.go, native version execution, and process tests. Target: the buffered-command part of A03.
- Set an internal
exec.Cmd.WaitDelayof one second in the common command construction path. This is an I/O teardown grace after cancellation or observed child exit, not a runtime deadline for healthy commands. It bounds drainage of pipes inherited by a surviving descendant while using the standard library's child waiting and error behavior. - Preserve
errors.Iscancellation/deadline identity when the governing context is done. Preserve ordinary*exec.ExitErrorandexec.ErrWaitDelaywhen appropriate. Retain the existing 30-second recovery context; its cancellation may be followed by bounded teardown, rather than an unbounded inherited-descriptor wait. Introduce no new public timing SLA or setting. - Route build's native version command through
process.Run, capturing stdout and stderr together. Preserve its current working-directory behavior, literalversionargument, exact expected output, and contextual failures. Stage 2 has already moved build's Git commands to the shared boundary. - Add ready-child/ready-descendant fixtures for cancellation and normal child exit with inherited descriptors. Check bounded return and error identity; clean up the fixture's descendants explicitly in test cleanup. Keep a generous test watchdog separate from the internal teardown grace.
Evidence: buffered Go/Git preparation can return after cancellation, healthy long-running commands continue until their caller cancels or they finish, and the existing source-publication recovery classifications remain unchanged.
Stage 5: Complete piped ownership and queued-read cancellation
Owners: PipedProcess in internal/process
and BlobReader. Targets: A03 and A18.
- Keep serialized batch exchanges and the existing
sync.Oncewait ownership. After a piped command starts, register an operation-context cancellation callback that closes its owned stdin/stdout pipes so an exchange or normal shutdown drain can unblock even if a descendant holds a descriptor. - Retain the callback's stop function and a completion signal. During
Wait, join the child and stop or join that callback before returning and before reading captured stderr. On healthy completion, stop the callback before releasing the derived context. Startup failures close acquired pipes and release the context. ExplicitCancelcontinues leaving the parent context unchanged. - Retain
BlobReader.Read's per-read cancellation hook and its completion join; it may delegate pipe interruption to the piped-process owner. Keep aborted sessions terminal, and preserve ordinary missing-object reuse. EnsureCloseuses the same cancellation/pipe lifetime and reaps the child. Healthy exchanges still consume stdout before the normal wait; the one-second grace does not become a lifetime limit on a healthy batch reader. - Recheck
ctx.Err()immediately after acquiringreader.mu, before session access or callback registration. A canceled queued request returns its own context error without aborting the healthy session. Retain the mutex; prompt cancellation while waiting for it remains outside this sprint. - Add controlled regressions for inherited-descriptor shutdown, cancellation during a body read, and a canceled queued request between a successful first read and a successful later read. Preserve double-close and parent-context behavior. Use readiness signals and joined cleanup, not timing alone.
Evidence: process and reader lifecycle tests pass under the race detector. Use one public preparation cancellation case to confirm caller-visible return; the test owns any descendant left running after the direct child is reaped.
Stage 6: Sanitize Git endpoint diagnostics
Owners: internal/git/remote.go, tag operations, publication, and the CLI. Target: A04.
- Add narrow internal Git URL display helpers. Mask the entire HTTP(S) userinfo component, covering password- and username-carried credentials. Retain useful scheme/host/path context. Keep non-HTTP Git forms unchanged.
- Use the helper for expected/resolved endpoints, endpoint changes, queries,
pushes, and reconciliation messages. Sanitize credential-bearing HTTP(S)
URL spans in captured Git error diagnostics before embedding them. If a
detected userinfo URL cannot be parsed safely for display, replace that span
with a redacted-URL marker. Preserve wrapped causes and error classification.
Where the cause's own text contains credentials, use a private error wrapper
whose
Errorrenders sanitized text and whoseUnwrapretains the cause; embedding the raw cause with%wwould expose its text again. This addresses URL credentials in owned diagnostics, not arbitrary secrets emitted by application checks or unrelated transport programs. - Render the CLI's
endpoint=field through the same display logic. KeepPublicationResult.Endpoint, captured transport URLs, URL rewrites, andExpectedPushURLcomparisons raw and exact. Clarify the public field's sensitivity in GoDoc without adding a new public accessor or field. - Cover password and username tokens, encoded userinfo, embedded Git diagnostic URLs, malformed display inputs, and ordinary SSH destinations. A public mismatch fixture must preserve exact mismatch detection while both the library error and CLI output hide placeholder credentials. Also exercise a later query/push failure and preserve the original cause.
Evidence: owned diagnostics are safe to display, while endpoint identity and transport behavior retain their selected contracts. Use placeholder credentials and local fixtures; live Git or forge credentials are unnecessary.
Stage 7: Preserve partial local tag evidence
Owners: CreateAnnotatedTag, publish.Publish, and publication tests. Target: A05.
- Retain the annotated tag object ID once its existing inspections establish that evidence. Return it with a later verification error rather than returning an empty string on every error.
- Assign any returned tag object to the publication result before handling the
error. Keep phase
tag_creationand statenot_publishedfor these failures. - After successful tag creation followed by failed inspection, identify
refs/tags/<tag>in the error and explain that the local tag may remain. When no ID was obtainable, retain the ref-level evidence and empty object field. Preserve the original cause and failed verification; perform no automatic local ref deletion, retagging, independent retry, or push. - Add public regressions using real repositories and a command wrapper that fails the first post-creation type inspection and a later inspection after the ID is known. Inspect the actual local ref independently and confirm retained evidence, original error, and absence of a remote push.
Evidence: the caller can distinguish possible retained local work from a verified tag object without a new public progress type. Update the relevant public comment and recovery guidance to reflect unavailable evidence accurately.
Stage 8: Normalize internal build results and completed artifacts
Owners: internal/build/build.go, facade conversion, and public build/CLI tests. Targets: A06 and A14.
- Remove internal
Result.MainPackage,BinaryName, andTargets; use normalizedResult.Settingsthroughout compilation, native smoke selection, and conversions. Keep publicBuildResultfields and receipt fields intact. Preserve early-failure normalization and result copying. - Build and hash each artifact in a local value before appending it to the completed artifact list. A hash failure names that path, preserves its cause, retains earlier completed artifacts, and leaves generated files in place. Later smoke or source-inspection failures still return all already completed artifacts. Introduce no compiled-but-unverified public result state.
- Extend the public post-compilation read-failure fixture to include an earlier successful target. Assert complete digests on the retained prefix, absence of an incomplete entry, accurate CLI presentation, and preserved source/ settings facts. Retain no-target, dirty-build, duplicate-target normalization, partial-target-failure, and version-injection coverage.
Evidence: public artifacts satisfy the documented digest contract, and prebuilt delivery still accepts the same normalized public results.
Stage 9: Share pure artifact declaration matching
Owners: internal/artifact, receipt validation, and delivery declarations. Target: A16.
- Introduce a pure helper accepting selected targets, expected-name inputs,
and recorded target/filename metadata in artifact-owned internal types.
Reuse
ExpectedBuildand existing component rules to check counts, target uniqueness, one artifact per selected target, and expected names. - Adapt both callers through explicit conversions. Keep receipt schema, absolute-path, identity, digest-syntax, and nonempty-target rules in the CLI. Keep delivery's empty/source-only behavior, file stats, manifest generation, and byte verification in their current owners and ordering.
- Preserve current acceptance rules; add no Go target allowlist or content
access during receipt loading. Keep
internal/artifactindependent of build, CLI, delivery, and forge packages. - Retain independent concrete expected filenames in receipt, delivery, and public receipt-to-delivery tests. Reuse mismatch cases rather than computing every expected value with the helper under test.
Evidence: schema and content validation remain distinct, with one owner for their shared declaration rule and unchanged source-only behavior.
Stage 10: Preserve allocation paths and temporary metadata cleanup
Owners: internal/tempdir, tag message files, and receipt files. Target: A07 part 1.
- In both
Outsideallocation branches, keep the originalMkdirTemppath untilAbs/EvalSymlinkssucceed. Use that original path for error-path removal. Retain the resolution error and report any failed removal with its path. Preserve outside-worktree selection and fallback behavior. - Capture deferred removal errors for owned tag-message and receipt temporary
files and join them with primary errors. A temporary path absent after a
successful rename is normal; ignore
os.ErrNotExistfor that removal. Keep successful receipt installation and caller output paths intact. - Preserve any verified local tag ID through a later metadata cleanup error, as established in Stage 7. Cleanup failure before the push remains a local publication failure; no extra remote action follows it.
- Use a narrow private, per-operation removal/resolution test seam where real filesystem failures are otherwise nondeterministic. Keep the seam behind internal wrappers, with standard functions in production and no mutable global hooks or public filesystem abstraction. Test path retention and joined causes, including the renamed-receipt absent-path case.
Evidence: failed resolution never loses the owned cleanup path, and routine successful receipt writes do not acquire a spurious cleanup error.
Stage 11: Report managed build cleanup with accurate outcomes
Owners: candidate build callback, native smoke build, managed delivery, and CLI delivery output. Target: A07 part 2.
- Use named returns or equivalent explicit finalization to join failed owned directory removal with a primary build/delivery error. Include the cleanup path and preserve completed artifacts, source facts, and remote observations.
- If remote delivery completed, return its
Completestate and asset lists together with the cleanup error. The public facade forwards both. The CLI returns operational status 1, explicitly reports remote completion plus local cleanup failure, and gives no instruction to redo completed hosted delivery. Earlier partial/conflict/unknown outcomes retain their original classification. - Keep managed temporary output outside the checkout. Caller-owned prebuilt artifacts and normal caller-selected build directories are not removed by this finalizer. Candidate build cleanup occurs before tagging as today.
- Test success-plus-cleanup-failure, primary-error-plus-cleanup-failure,
cancellation, and confirmed hosted completion with cleanup failure. Use a
private per-operation remover parameter at the internal operation boundary
where needed for deterministic failures; keep production entry points using
os.RemoveAll. Test the outcome, not only a standalone join helper.
Evidence: errors identify leaked paths without misreporting remote state or
discarding existing causes. Update delivery/CLI guidance for Complete plus
a local operational error and preserve ordinary cleanup success cases.
Stage 12: Bound manual asset redirects
Owners: internal/gitea/assets.go and adapter/ delivery tests. Target: A08.
- Count followed redirect hops in
openAsset. Allow ten hops: the initial request plus at most ten follow-up requests. After ten followed redirects, a further redirect response is closed and rejected before requesting its target. A successful response after the tenth hop remains accepted. - Keep fragment normalization, exact-cycle handling, invalid-userinfo rejection, and per-origin token checks. Close every intermediate/rejected body. Return the existing unverifiable-content failure classification with useful context. Add no public override or automatic operation timeout.
- Test zero hops, exactly ten, and an eleventh attempted hop with distinct URLs. Retain same-origin, cross-origin, return-to-origin, and exact-cycle checks. Use local servers and request counters to verify the boundary.
- Preserve shared outcome mapping: read-only verification failure leaves
NotAttempted, orPartialwhen this invocation created the page; ambiguity after an attempted asset write still follows existing reconciliation rules.
Evidence: the selected hop count is unambiguous and authorization never follows the token to another origin. Document the limit in the Gitea integration owner.
Stage 13: Bound remote content comparison by the declaration
Owners: internal/delivery/remote_assets.go and delivery/artifact fixtures. Target: A09.
- Pass expected local size into the digest comparison. Read at most that size
through a limited reader, then probe one additional byte. Keep the extra-byte
fact separate from an
int64total soMaxInt64 + 1never overflows. - Distinguish definite size mismatch from inspection failure. Short or excess
content becomes
AssetConflicting; equal-length content still requires digest equality. A non-EOF read error, close error, or context error remains unverifiable with its cause retained. Close the stream on every path. - Apply the same verification during upload reconciliation. A mismatch there conflicts; an unresolved read after a possibly successful write remains unknown under the existing policy. Keep local hashing before hosted writes, additive uploads, and asset observation categories unchanged.
- Test empty, shorter, equal/matching, equal/different, and oversized streams, plus a read returning data with an error, close failure, and cancellation. Count bytes in a controlled stream to prove the declaration-derived bound. Include a public prebuilt-delivery case and retain manifest comparison.
Evidence: remote metadata size/content length is not used as proof of matching bytes, and legitimate artifact size has no new global cap.
Stage 14: Bound retained status-only Go diagnostics
Owners: internal/gotool/gotool.go, its tests, and output benchmarks. Target: A10.
- Give combined capture an explicit full-output mode and a status-diagnostics
mode. Full mode retains
Tool.Outputbytes and the existing ownership transfer. Status mode retains the last 1,048,576 bytes and whether earlier bytes were omitted. Use a lazy bounded circular tail so repeated small writes copy in proportion to incoming data rather than shifting a 1 MiB buffer on every write. Keep synchronization around capture and forwarding. - Use status mode for
Tool.Runand dependency preparation. Preserve complete forwarding to existing optional writers, short-write/error handling, quiet behavior without a writer, and the separate preparation Go environment. Keep configuration-discovery JSON andTool.Outputcomplete. Add no public output field or diagnostic-retention setting. - On failed status commands, include a clear truncation notice only when needed, followed by the retained tail, while wrapping original process and forwarding errors. Successful status calls release retained diagnostics.
- Adapt existing output tests and benchmarks to exercise both modes. Test below/exact/above budget, a single oversized write, wrapped small writes, concurrent stdout/stderr, forwarded bytes, and error identity. Benchmark modest output and 8 MiB/32 KiB-chunk output with allocated bytes reported.
Evidence: the retained status tail is bounded, full-output consumers keep all bytes, and forwarded output remains complete. Update the internal Go-output guide and its benchmark description to the implemented modes.
Stage 15: Separate validation sequence and tree lifetime
Owners: internal/validation/validation.go and validation lifecycle/diagnostic tests. Target: A13.
- Extract private Go-command and committed-tree execution functions. Keep the visible order: tests, selected full vet, selected compilation, forbidden files, formatting, workspace files, local replacements, file size, Markdown. Shared-file selection alone still validates explicit file presence.
- Let the committed-tree sequence own its close and the last content-reading check. Preserve tree-load failure precedence, first check failure, and the rule that reader-close failure replaces success only after a content read. Keep context and underlying diagnostic causes through the public facade.
- Preserve nil versus empty shared files and optional check selections, operation-local Go settings reuse, and single execution of additional checks and build callbacks by their existing owners. Use private functions and explicit check blocks; retain current package and public interfaces.
Evidence: existing combined-check order, scope, Markdown, and lifecycle tests remain meaningful. Add a focused case only if existing tests leave one of the preserved precedence or metadata-only close behaviors unprotected.
Stage 16: Extract private CLI workflows
Owners: cmd/releasekit/main.go and CLI tests. Target: A15.
- Extract named private handlers for check/publication and for build. Keep
argument parsing, containing-repository resolution, version dispatch, and
command routing in
run. Existing delivery handlers remain the local model. - Preserve profile loading, captured-candidate environment, expected module and endpoint mapping, receipt invalidation before build-error reporting, receipt verification, partial-artifact output, and all exit classifications. Carry Stage 6's safe endpoint display and Stage 11's cleanup reporting into the handlers without adding command flags or public interfaces.
- Keep the CLI calling the public facade for release operations. Existing internal path/configuration helpers retain their current role. Reuse the command tests for profile errors, successful operations, known failures, and unknown publication/delivery outcomes.
Evidence: the dispatcher is small while command behavior and failure evidence match the selected contracts. No new CLI framework is needed.
Stage 17: Remove incidental assertions and unused helpers
Owners: Markdown and Linux delivery-read tests, public publication tests, release identity, and local tag helpers. Targets: A19 and A20.
- Remove Markdown cache pointer-identity assertions; retain unique parsing checks and identical-blob source-relative link behavior. Existing behavioral tests remain the protection for correctness.
- Remove
TestDeliverReadsLocalBinaryOnceForVerificationAndOnceForUploadas an exact inotify-open-count contract. Retain independent tampering, pre-write verification, and uploaded-byte checks. Use the existing delivery benchmark to observe read/verification cost; no replacement exact-open assertion is required. Stage 1 handled successful-path query counts. - Remove only the unused
FromCommittedSelectionwrapper, keeping the private implementation and liveFromCommitted/ResolveCommittedSelectionpaths. - Remove unused
InspectLocalTagand its direct test call, preserving the test's other full-tag/source assertions and the live candidate guard. Retain tree accessors and constructors used meaningfully by tests/benchmarks.
Evidence: source references show no remaining use of removed symbols; caller behavior and public exports remain covered. Avoid tests that merely mirror the deleted helpers or assert a new incidental call count.
Stage 18: Record the deferred resource assessments
Targets: A11 and A17. Deliver evidence in their status notes here; accepted production behavior remains as defined in audit.md.
-
For A11, inventory local repository/release/attachment JSON fixtures and checked-in release-note sizes. Record measured byte sizes, the kinds of responses represented, and missing evidence about deployment/protocol maxima. Local fixtures establish observed sizes, not a supported maximum. Record that JSON size/time caps and new configuration remain deferred; preserve current cancellation and ambiguous-write handling. Live service queries or an external sizing decision are not prerequisites to finish this sprint.
-
For A17, add
BenchmarkFileSizeExclusionsin a validation benchmark file. Compare the current scan with a benchmark-only normalized set/ancestor prototype for 1,000 and 10,000 paths; 1, 10, 100, and 1,000 exclusions; and representative shallow/deep paths with early matches and nonmatches. Count one index construction per simulated operation, report allocations, and prepare unrelated fixture strings outside timing. Preserve literal semantics in the comparison; do not add the prototype to production code. -
Run the benchmark with a bounded measurement interval, for example:
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go test ./internal/validation \ -run '^$' -bench '^BenchmarkFileSizeExclusions$' -benchtime=100ms -count=3 -
Record toolchain/platform, command, timings/allocations, and representative common/large-list tradeoffs. Keep production exclusion matching unchanged in this sprint; the assessment supplies evidence for a later adoption decision. Mark both items as assessment completed / production change deferred, rather than claiming either resource policy is implemented.
Evidence: both deferred items have a concrete disposition and useful evidence without inventing unapproved protocol limits or performance thresholds.
Stage 19: Verify the complete target and update current documentation
-
Inspect the combined implementation against all A01–A20 outcomes and the stage table. Confirm the fixes interact correctly: original-object reads use the shared canceled-process boundary; partial tag evidence survives cleanup errors; completed artifacts feed shared declarations; content limits preserve preflight/write order and reconciliation outcomes; CLI output presents causes and reached state accurately.
-
Complete canonical documentation updates in GoDoc,
docs/cli.md, consumer publication/build/delivery guides,docs/integrations/gitea.md, and relevant internal guides. Document the accepted redirect and diagnostic policies, raw endpoint sensitivity, and completed hosted state with cleanup error. Keep implementation mechanics out of user flows. Preserve public facade shape, receipt schema, source-only release behavior, and the Go baseline. -
Format changed Go files and run from the repository root:
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go test ./... GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go test -race ./... GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go run ./internal/apicheckRun focused regressions first as needed while completing their owners. Reuse successful checks for unchanged content. Full-suite green results complement, rather than replace, the targeted failure evidence above.
-
Check local documentation links/fragments and Markdown whitespace. Review the diff for accidental public exports, stronger target/path restrictions, new global deadlines, secret values, unrelated changes, and altered caller ownership. Resolve failures within the selected scope before finishing.
-
Update this plan's stage statuses and record final verification. Keep A11 caps and A17 indexing explicitly deferred, with Stage 18 evidence. Retain the source audit reports for review and traceability. Commit completed nonempty work with plain English messages and report the result, remaining deferrals, and any actual limitations. Release preparation remains governed by the maintainer runbook.
Completion means the selected repairs and maintenance are implemented, their behavioral evidence passes, current contracts are documented, and the two accepted deferrals have assessment records. Intermediate stages introduce no extra compilation, review, or deployment gates.