Snapshot of the in-flight state that already existed, identically, in both this worktree and the main checkout before this session began: the initial HTTP Client platform implementation (previously untracked), the redis-lab removal, and the JPA / object-storage / notification integration work. Kept separate from this session's HTTP Client review response, which lands in the following commit, so the two bodies of work stay reviewable apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.0 KiB
Verification Purity Refactoring Design
Date: 2026-08-02 Status: approved by the user's instruction to apply the P1/P2 review sequentially Scope: stale traceable JAR verification/cleanup and public-path snapshot verification/update
Context
Two root Gradle verification paths currently mutate files while they are expected to be safe gates:
- every
Jartask deletes stale traceable archives indoFirst, andverifyNoStaleTraceableJarsdepends oncleanStaleTraceableJars; verifyPublicPathSnapshotcreates a missing snapshot and updates drift when-PapprovePublicPathChangeis supplied.
That makes check capable of hiding the state it is meant to detect. This batch restores the
standard contract: verification observes and fails, while explicitly named maintenance tasks own
writes.
Considered Approaches
Keep the root build logic in place and inspect source text in tests
This is the smallest diff, but a source assertion cannot prove task side effects. Rejected.
Invoke the entire repository build from a copied checkout
This tests the actual root build but requires copying all 19 leaves and resolving every root plugin for two small contracts. It is slow and couples the tests to unrelated configuration. Rejected.
Extract only the two task concerns into applied Gradle scripts and exercise them with TestKit
Selected. The production root applies the same scripts that an isolated functional fixture uses. The fixture observes exit status and filesystem state, so it proves behavior rather than source shape. This is a bounded extraction required for testability, not the broad P2 root-build rewrite.
Archive Hygiene Contract
gradle/archive-hygiene.gradle owns stale traceable archive discovery and the two root tasks:
verifyNoStaleTraceableJarsreports every stale archive and fails without deleting anything;cleanStaleTraceableJarsdeletes only names matching the traceable archive pattern for a knownJartask and never deletes the current archive;- normal
jar/bootJarexecution never performs cleanup.
The existing traceable version naming and manifest metadata remain unchanged.
Public-Path Snapshot Contract
gradle/public-path-snapshot.gradle owns canonicalization and two root tasks:
verifyPublicPathSnapshotfails when the env file or committed snapshot is missing, when content drifts, or when the update-only approval property is passed to the verifier. It never creates directories or writes files;updatePublicPathSnapshotrequires-PapprovePublicPathChangeand writes the canonical snapshot.
A clean-worktree requirement is intentionally not used: the normal update workflow necessarily has
an intentional .env change. Explicit task naming, the approval property, and the resulting diff
are the review boundary.
The canonical header names updatePublicPathSnapshot, so documentation and the committed snapshot
do not instruct users to mutate through a verification task.
Testing
BuildVerificationPurityContractTest runs from an isolated functionalTest source set using Gradle
TestKit against temporary projects that apply the production scripts directly. Keeping TestKit off
the ordinary testRuntimeClasspath prevents Gradle's SLF4J provider from replacing Logback during
Spring tests. It proves:
- a normal
jarleaves a matching stale archive untouched; - verification fails and preserves the stale archive;
- explicit cleanup deletes the stale archive but preserves the current archive;
- missing/drifted public-path snapshots cause read-only failure;
- the verifier rejects the update approval property;
- only the explicit updater with approval creates or changes the snapshot.
Non-Goals
- no change to archive naming, versions, manifests, production dependency versions, or project edges;
- only the new isolated functional-test configurations are added to
app-bootstrap/gradle.lockfile; - no public-path allow-list value change;
- no broad root Gradle convention-plugin migration;
- no staging, commit, amend, or push by an agent.