Write the staged audit remediation plan
This commit is contained in:
@@ -1,269 +1,108 @@
|
||||
# Audit remediation roadmap
|
||||
|
||||
## Status and baseline
|
||||
## Status and scope
|
||||
|
||||
Proposed on 2026-11-01 against `899e7f1`. Implementation has not started.
|
||||
Agreed remediation target as of 2026-11-01. Implementation is pending against
|
||||
baseline `59bb074`.
|
||||
|
||||
This roadmap consolidates all three findings in the
|
||||
[functional correctness audit](correctness.md) and all five findings in the
|
||||
[interface audit](interfaces.md). Those documents retain the reproduction
|
||||
circumstances and evidence. This document owns the proposed corrections,
|
||||
implementation sequence, and completion criteria.
|
||||
This roadmap defines the desired behavior and scope for all three findings in
|
||||
the [functional correctness audit](correctness.md) and all five findings in the
|
||||
[interface audit](interfaces.md). Those documents retain their reproduction
|
||||
circumstances and evidence. The [implementation plan](implementation.md) owns
|
||||
staging, code changes, regression checks, and completion tracking.
|
||||
|
||||
The baseline has separate orchestration and runtime facades, internal candidate,
|
||||
validation, build, preparation, and publication services, and shared delivery
|
||||
policy behind the neutral forge boundary. The corrections fit those existing
|
||||
owners. The ordinary and race-enabled offline suites and compiled boundary
|
||||
checks passed during the audits; they do not cover all identified defects.
|
||||
## Purpose and architectural scope
|
||||
|
||||
## Targeted end state
|
||||
ReleaseKit owns routine release mechanics so consumers supply product facts and
|
||||
product-specific checks with little release-related code. As recorded in
|
||||
[ADR 0002](../adr/0002-routine-releases.md), internal complexity is justified
|
||||
when it reduces caller-owned release work. In particular, callers can reuse a
|
||||
repository location across preparation and subsequent orchestration without
|
||||
normalization code or another configuration option.
|
||||
|
||||
- Incomplete authoritative tag observations retain an unknown publication
|
||||
outcome after a failed push acknowledgment.
|
||||
- Dependency preparation uses ordinary module discovery from its selected
|
||||
directory despite an inherited or persistent `GOFLAGS=-modfile=...` setting.
|
||||
- Candidate checking establishes that its derived release tag is a valid Git
|
||||
ref before accepting it as an unused local tag.
|
||||
- Cancellation during build source inspection remains identifiable through
|
||||
the returned error chain.
|
||||
- Asset operations classify a missing service-provided release identity as a
|
||||
malformed observation. Existing page-only reads retain their current minimal
|
||||
response requirements.
|
||||
- Preparation resolves the containing checkout root automatically, matching
|
||||
other orchestration operations. Standalone preparation retains the supplied
|
||||
directory as its base.
|
||||
- Delivery documentation accurately describes identity requirements for empty
|
||||
prebuilt results and credential preflight before full artifact verification.
|
||||
The existing public orchestration and runtime facades and internal package
|
||||
boundaries remain appropriate. These corrections use the existing public types,
|
||||
receipt schema, module/tag conventions, and publication/delivery model.
|
||||
|
||||
These corrections preserve the existing public types, receipt schema, release
|
||||
identity conventions, and publication/delivery model. Work stays focused on the
|
||||
reported cases: Git supplies ref-name rules; local builds retain their current
|
||||
filesystem choices; preparation retains network access and caller operational
|
||||
settings; and page-only reads retain their current field requirements. Existing
|
||||
source-verification observations and preflight evidence limits continue to
|
||||
apply.
|
||||
## Desired behavior
|
||||
|
||||
## Finding coverage
|
||||
### Incomplete publication observations
|
||||
|
||||
| Audit finding | Work unit |
|
||||
| --- | --- |
|
||||
| Correctness 3: incomplete reconciliation becomes conflict | 1 |
|
||||
| Correctness 2: ambient module-file redirection | 2 |
|
||||
| Correctness 1: invalid derived tag accepted by Check | 3 |
|
||||
| Interfaces 1: source-inspection cancellation identity | 4 |
|
||||
| Interfaces 2: unusable successful release handle | 5 |
|
||||
| Interfaces 3: preparation repository anchor | 6 |
|
||||
| Interfaces 4: empty-prebuilt GoDoc | 7 |
|
||||
| Interfaces 5: hashing before every hosted request | 8 |
|
||||
After a failed push acknowledgment, a query containing only a peeled tag record
|
||||
provides insufficient evidence about the exact annotated tag object.
|
||||
Publication remains unknown and retains the original push cause. A complete
|
||||
response works in either record order. Existing exact-object matches, genuinely
|
||||
absent tags, different objects, and exact-object-only responses retain their
|
||||
current outcomes.
|
||||
|
||||
## Implementation sequence
|
||||
### Dependency preparation and ambient module files
|
||||
|
||||
Each unit includes its relevant validation and canonical documentation updates.
|
||||
Complete the units as focused changes using the repository's ordinary commit
|
||||
policy. Record completion here and update the corresponding audit finding's
|
||||
status when its correction is verified. The sequence requires local repository
|
||||
work and automated checks; it adds no pilot, intermediate release, or external
|
||||
review step.
|
||||
Preparation uses ordinary Go module discovery from its selected directory even
|
||||
when inherited or persistent `GOFLAGS` selects an alternate module file. It
|
||||
retains other effective flags and existing proxy, private-module,
|
||||
authentication, checksum, cache, workspace, and local-toolchain behavior.
|
||||
Go retains its existing checksum-update behavior, including upward declaration
|
||||
discovery for standalone package-directory preparation.
|
||||
|
||||
### 1. Preserve uncertainty for incomplete remote tag observations
|
||||
### Valid candidate tags
|
||||
|
||||
**Status:** open. **Source:** correctness finding 3.
|
||||
Candidate checking establishes that the complete derived release tag is a valid
|
||||
Git ref before accepting it as unused. Git's own ref rules remain the authority.
|
||||
The correction concerns release candidate validity; standalone local builds
|
||||
retain their existing filesystem choices and version rules.
|
||||
|
||||
**Owners:** `internal/git` ref parsing and `internal/publish` recovery, with CLI
|
||||
outcome verification.
|
||||
### Identifiable build cancellation
|
||||
|
||||
Finalize tag observations after the entire query response has been parsed.
|
||||
A peeled record without its exact tag-object record is an inconsistent or
|
||||
unreadable observation. Use the existing ref-state/error vocabulary so
|
||||
publication reconciliation retains `PublicationUnknown` and the original push
|
||||
cause. Keep valid records usable in either order; a peeled record may precede
|
||||
its exact tag record.
|
||||
Cancellation or deadline expiration during build source inspection remains
|
||||
identifiable through the error chain. Ordinary Git failures retain useful
|
||||
diagnostics, and partial results retain already completed artifacts.
|
||||
|
||||
**Completion evidence:** a local Git recovery fixture performs the intended
|
||||
push, loses its acknowledgment, and supplies only the peeled record. The public
|
||||
result is unknown, the cause remains inspectable, and the CLI uses status 3.
|
||||
Existing exact-match, absent-tag, and different-object recovery outcomes still
|
||||
work, along with complete records in either order. Query finalization retains
|
||||
both genuinely absent results and valid exact-object-only results.
|
||||
### Gitea release identity at asset use
|
||||
|
||||
### 2. Override the redirecting module-file flag during preparation
|
||||
A backend-produced handle with a missing or nonpositive service release ID is a
|
||||
malformed observation when an asset operation needs that ID. A handle of the
|
||||
wrong type remains an invalid request. Locally rejected uploads retain
|
||||
not-attempted write evidence.
|
||||
|
||||
**Status:** open. **Source:** correctness finding 2.
|
||||
Existing page-only reads retain their current minimal response requirements.
|
||||
This correction adds no universal positive-ID or page-URL requirement to a
|
||||
successful release lookup and preserves existing delivery progress semantics.
|
||||
|
||||
**Owners:** `internal/gotool` dependency preparation and its CLI integration.
|
||||
### Consistent preparation paths
|
||||
|
||||
Give `go mod download` an explicit empty `-modfile` argument. Command-line flag
|
||||
precedence overrides an inherited or persistent alternate module-file selection
|
||||
and restores Go's ordinary module discovery. A local Go 1.26.10 probe verified
|
||||
this behavior from both a module root and its package subdirectory, with each
|
||||
flag source.
|
||||
Within a Git checkout, preparation resolves its containing root automatically
|
||||
and interprets `ModuleDir` relative to that root. Empty selection means the
|
||||
root module, consistently with `Check`, `Build`, and `Deliver`. This includes
|
||||
calls made from checkout subdirectories and filesystem aliases.
|
||||
|
||||
This is narrower than replacing all `GOFLAGS` or disabling the persistent Go
|
||||
environment. Preserve the other effective flags and the current proxy,
|
||||
private-module, authentication, checksum, cache, workspace, and local-toolchain
|
||||
behavior. Directory selection follows the checkout-root resolution in unit 6;
|
||||
within the resolved selection, preserve Go's existing checksum-update behavior
|
||||
and ordinary module discovery. Standalone package-directory preparation retains
|
||||
upward declaration discovery.
|
||||
Outside a Git checkout, preparation retains the supplied directory as its base
|
||||
and the existing relative module selection. Standalone use remains supported.
|
||||
It retains its existing Go-only use when Git is unavailable and the directory
|
||||
can be identified as outside a checkout.
|
||||
Discovery distinguishes this case from cancellation, permission failures, and
|
||||
other Git errors, which remain failures. Existing symlink and containment rules
|
||||
and the CLI's root normalization continue to apply.
|
||||
|
||||
**Completion evidence:** exercise both inherited and persistent `-modfile`
|
||||
settings against different module graphs. Preparation consumes the ordinary
|
||||
selected graph, including standalone use where Go discovers its declaration
|
||||
above the working directory. Verify the existing network/private-module/cache
|
||||
settings remain available and that unrelated flags retain their behavior. Use
|
||||
test-owned `GOMODCACHE` directories for every synthetic-module download. Keep the
|
||||
existing binary CI preparation ordering and cancellation/error propagation covered.
|
||||
### Empty prebuilt results
|
||||
|
||||
Document the preparation flag override in its GoDoc and the
|
||||
[Go environment guide](../internal/gotool.md). Update command fixtures for the
|
||||
intentional invocation change; use graph-selection behavior as the regression
|
||||
assertion rather than relying only on argument matching.
|
||||
Page-only callers ordinarily omit both `Build` and `Prebuilt`. A supplied
|
||||
prebuilt result with no targets or artifacts still identifies the matching
|
||||
repository, module, tag, commit, and version. Documentation states that
|
||||
requirement clearly. A zero `BuildResult` gains no new compatibility behavior.
|
||||
|
||||
### 3. Validate derived tag names during candidate capture
|
||||
### Artifact-verification order
|
||||
|
||||
**Status:** open. **Source:** correctness finding 1.
|
||||
Documentation consistently describes cheap local/source checks, read-only
|
||||
credential preflight, full local artifact verification, and then hosted writes.
|
||||
Digest verification completes before hosted writes. Credential preflight can
|
||||
precede that verification and confirms only the access evidence exposed by the
|
||||
backend.
|
||||
|
||||
**Owners:** `internal/candidate` and the shared Git ref-validation boundary.
|
||||
## Scope boundaries
|
||||
|
||||
Apply the existing Git ref-name check to the complete derived tag before local
|
||||
tag absence is accepted during candidate capture. Keep name validity distinct
|
||||
from the existence query: exit status 1 from `show-ref` alone cannot establish
|
||||
both. Reuse the same rule at any candidate recheck boundary that needs it,
|
||||
without duplicating Git's character rules in ReleaseKit.
|
||||
|
||||
**Completion evidence:** public `Check` fails for derived tags containing the
|
||||
reported space and `.lock` directory components, before validation callbacks
|
||||
run. Ordinary root, nested, slash-containing, and supported major-version tags
|
||||
still work. Preserve the captured identity in failure results and existing
|
||||
publication guards. Standalone `Build` retains its current local-build behavior.
|
||||
|
||||
Update candidate guidance only as needed to explain the local failure; this
|
||||
unit introduces no new version syntax or blanket directory-name policy.
|
||||
|
||||
### 4. Preserve cancellation during build source-state inspection
|
||||
|
||||
**Status:** open. **Source:** interfaces finding 1.
|
||||
|
||||
**Owner:** `cleanSource` in `internal/build/build.go`.
|
||||
|
||||
When the Git status command fails and its operation context is canceled or has
|
||||
expired, retain that context error in the returned chain, following the
|
||||
neighboring build helpers or the existing process boundary. Ordinary Git errors
|
||||
retain their current useful diagnostics. Keep the partial build result intact.
|
||||
|
||||
**Completion evidence:** interrupt source inspection before compilation and
|
||||
after completed artifacts exist. `errors.Is` identifies cancellation, and a
|
||||
focused deadline case identifies deadline expiration. The latter build result
|
||||
retains its completed artifacts. Retain existing managed-delivery cancellation
|
||||
and temporary-output cleanup coverage; add an integration case only if the
|
||||
helper-level/public-build coverage leaves a distinct propagation risk.
|
||||
|
||||
### 5. Classify incomplete Gitea handles at asset use
|
||||
|
||||
**Status:** open. **Source:** interfaces finding 2.
|
||||
|
||||
**Owner:** Gitea backend handle interpretation in `internal/gitea/backend.go`.
|
||||
|
||||
Keep `FindRelease` usable for page-only reads with the existing minimal response
|
||||
fields. When an asset operation needs the positive release ID and a
|
||||
backend-produced handle lacks it, return the existing malformed-response
|
||||
classification with a useful missing-identity diagnostic. Distinguish this from
|
||||
a handle of the wrong type, which remains an invalid request. Apply the
|
||||
distinction consistently to listing and uploading; an upload rejected locally
|
||||
retains not-attempted write evidence.
|
||||
|
||||
**Completion evidence:** feed a lookup response with a missing, zero, or negative
|
||||
ID through the backend. Page-only matching still succeeds under its existing
|
||||
rules; binary asset use fails with the malformed classification before an
|
||||
asset request. Wrong-type handles remain invalid requests, valid IDs continue
|
||||
to work, and existing page/write-progress outcomes remain accurate. Retain
|
||||
`TestBackendFindReleaseDoesNotRequireWriteResponseFields` or equivalent
|
||||
behavioral coverage. Update the integration guide's error description as needed.
|
||||
|
||||
### 6. Resolve preparation's checkout root automatically
|
||||
|
||||
**Status:** open. **Source:** interfaces finding 3.
|
||||
|
||||
**Owners:** the preparation facade, shared Git/selection boundaries,
|
||||
`DependencyPreparationRequest` GoDoc, and consumer preparation guidance.
|
||||
|
||||
Resolve the containing checkout root from `RepositoryDir` before applying
|
||||
`ModuleDir`. Within a checkout, interpret `ModuleDir` relative to that root;
|
||||
empty selection means the root module, consistently with `Check`, `Build`, and
|
||||
`Deliver`. For standalone use outside a Git checkout, retain the supplied
|
||||
directory as the base and apply the existing relative module selection there.
|
||||
|
||||
Keep this normalization inside ReleaseKit so callers can reuse a repository
|
||||
location across operations without normalization code or a new setting. This
|
||||
applies [ADR 0002's priority](../adr/0002-routine-releases.md) of minimizing
|
||||
caller-owned release work. Retain the CLI's existing root normalization and
|
||||
shared symlink/containment rules. Distinguish standalone use from discovery
|
||||
failures; cancellation, permission failures, and other Git errors remain
|
||||
errors rather than silently selecting another base.
|
||||
|
||||
**Completion evidence:** cover calls from the checkout root and its
|
||||
subdirectories, default and explicit nested-module selections, symlink-resolved
|
||||
paths, standalone directories, and discovery failures. Include combined coverage
|
||||
with unit 2 showing that preparation and subsequent orchestration select the
|
||||
same module from the same repository location and `ModuleDir`, even with an
|
||||
ambient alternate module file. Preserve standalone package-directory discovery
|
||||
and the existing CLI behavior. Update GoDoc and consumer guidance to describe
|
||||
the selected interpretation and the change for checkout-subdirectory callers.
|
||||
|
||||
### 7. Clarify empty prebuilt results
|
||||
|
||||
**Status:** open. **Source:** interfaces finding 4.
|
||||
|
||||
**Owners:** `DeliveryRequest` GoDoc and
|
||||
[delivery consumer guidance](../consumers/delivery.md#go-api).
|
||||
|
||||
Describe a page-only prebuilt result as having no targets or artifacts while
|
||||
still identifying the same repository, module, tag, commit, and version.
|
||||
Present nil `Build` and nil `Prebuilt` as the ordinary page-only request.
|
||||
Keep the existing identity checks and matching-empty-result behavior.
|
||||
|
||||
**Completion evidence:** the exported GoDoc and guide agree with
|
||||
`validateBuildIdentity`, and no wording implies that `&BuildResult{}` is accepted.
|
||||
Review existing page-only and prebuilt identity coverage; this wording correction
|
||||
does not require a new zero-result compatibility path or additional tests.
|
||||
|
||||
### 8. Correct the documented artifact-verification order
|
||||
|
||||
**Status:** open. **Source:** interfaces finding 5.
|
||||
|
||||
**Owner:** the prebuilt paragraph in
|
||||
[delivery consumer guidance](../consumers/delivery.md#go-api).
|
||||
|
||||
Replace the claim that digest checks precede every hosted request with the
|
||||
selected order: cheap local/source checks, read-only credential preflight,
|
||||
full artifact verification, then hosted writes. Keep the concise statement that
|
||||
local verification completes before hosted writes consistent across GoDoc and
|
||||
current guidance.
|
||||
|
||||
**Completion evidence:** affected descriptions agree with the implementation,
|
||||
[ADR 0006](../adr/0006-neutral-forge-delivery-and-preflight.md), and existing
|
||||
`TestAutomaticPreflightFailurePrecedesPrebuiltArtifactHashing` coverage. This
|
||||
unit changes wording and preserves the current operation order.
|
||||
|
||||
## Final verification and completion
|
||||
|
||||
Run focused regression checks with each behavioral correction. Once the units
|
||||
are complete, run the ordinary offline suite and compiled boundary check:
|
||||
|
||||
```sh
|
||||
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go test ./...
|
||||
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go run ./internal/apicheck
|
||||
```
|
||||
|
||||
Use race-enabled checks for affected subprocess/cancellation and adapter paths
|
||||
where the change warrants them. The audit's existing full race-suite result is
|
||||
baseline evidence; repeat broader checks when implementation changes or failures
|
||||
justify it. Keep fixtures local, deterministic, and independent of real
|
||||
credentials, with isolated synthetic module caches.
|
||||
|
||||
Review public errors/results, CLI statuses, and canonical documentation against
|
||||
the completion evidence above. Validate affected links and prose whitespace.
|
||||
Mark this roadmap complete when all eight work units and their corresponding
|
||||
audit findings have been addressed and verified, including the selected path-anchor
|
||||
interpretation. The initial pass that creates this roadmap changes only this
|
||||
document.
|
||||
The corrections retain the current source-verification observations, bounded
|
||||
publication recovery, explicit forge selection, and additive hosted delivery
|
||||
policy. They introduce no new public configuration knobs, compatibility shims,
|
||||
release procedure, pilot release, or intermediate human-review requirement.
|
||||
The targeted sprint reaches this complete end state through local repository
|
||||
work and automated validation.
|
||||
|
||||
Reference in New Issue
Block a user