Record error handling audit finding

This commit is contained in:
2026-11-02 01:41:31 +00:00
parent 3754242969
commit 3d7a691338

View File

@@ -0,0 +1,54 @@
# Error-handling audit
Reviewed baseline: `3754242` on `main`. The review traced public errors and
partial results through candidate validation, Git publication, build and
preparation, subprocess execution, and hosted delivery. Existing findings about
subprocess cancellation, publication integrity, temporary cleanup, and remote
resource consumption are retained in the [correctness](01-correctness.md),
[concurrency](04-concurrency.md), [resource](05-resources.md), and
[security](07-security.md) audits rather than duplicated here.
The existing `internal/delivery`, `internal/git`, and `internal/gitea` tests
passed with the Go test cache. An isolated temporary repository, a copy of the
Git and process packages, and a Git wrapper were used to exercise the finding
below; no production source or repository tests were modified.
## A post-creation inspection failure hides a retained local tag
**Relevant code:** [CreateAnnotatedTag](../../../internal/git/tag.go),
[publish.Publish](../../../internal/publish/publish.go), and the public
[PublicationResult](../../../publish.go).
**Failure condition:** Git successfully creates the annotated local tag, but
a subsequent `cat-file` or `rev-parse` inspection fails, for example because
the process is interrupted or the local Git operation encounters an error.
`CreateAnnotatedTag` returns an empty object ID on every such error. Its caller
returns immediately without setting `PublicationResult.TagObject`. The local
tag is not removed, and the next publication attempt's candidate check rejects
that existing tag. No remote push has been attempted at this point.
**Expected and actual behavior:** `PublicationResult.TagObject` is documented
as the local annotated tag object ID when created, and publication results are
intended to give callers evidence for recovery. The result instead reports
`not_published` and the tag-creation phase with an empty object field even
though a local tag may remain. The returned error identifies the failed
inspection but does not explain that tag creation already succeeded. An
operator may have to discover the tag independently before deciding how to
recover; the absence of an object ID is not evidence that no tag exists.
**Evidence:** In a temporary repository, a wrapper delegated real Git commands
except for the post-creation `cat-file -t` inspection, which returned an error.
`CreateAnnotatedTag` returned an empty object ID and an error, while an
independent Git query confirmed the local tag existed. The public result's
empty field follows from the caller's immediate error return; the probe did
not run the complete public publication workflow.
**Potential approaches:** Preserve any verified object ID obtained before a
later failure and return it with the error. When creation succeeded but the
object could not be inspected, report explicitly that the local tag may exist
and identify its ref for manual inspection. Keep the failed verification and
original cause visible, never treat the tag as publishable without the existing
checks, and avoid deleting or changing a ref whose current ownership is not
established. A focused regression can force an inspection failure after
successful creation and check both the local ref and returned recovery
information.