Files
clean-architecture-backend-…/docs/superpowers/plans/2026-08-02-verification-purity-refactoring.md
T
DongHyeonkaandClaude Opus 5 5f10b791d3 chore: record pre-existing uncommitted repository state
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>
2026-08-11 16:48:43 +09:00

5.1 KiB

Verification Purity Refactoring Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Make stale-JAR and public-path verification strictly read-only while preserving explicit cleanup/update workflows.

Architecture: Extract only these two root Gradle concerns into applied scripts so the production tasks can be exercised by isolated Gradle TestKit fixtures. Verification tasks only observe and fail; clean* and update* tasks are the sole writers.

Tech Stack: Java 21, Gradle 9.0.0 Groovy DSL, Gradle TestKit, JUnit 5, AssertJ.

Global Constraints

  • Preserve all existing P0 changes in the dirty worktree.
  • Preserve the 19-leaf registry and every production project dependency edge.
  • Normal archive tasks and every verify* task must be read-only.
  • updatePublicPathSnapshot requires -PapprovePublicPathChange.
  • Agents do not stage, commit, amend, or push.

Task 1: Add Functional RED Contracts

Files:

  • Create: src/app-bootstrap/src/functionalTest/java/dev/caskeleton/bootstrap/contract/BuildVerificationPurityContractTest.java
  • Modify: src/app-bootstrap/build.gradle
  • Modify: src/app-bootstrap/gradle.lockfile

Interfaces:

  • Consumes: production scripts at src/gradle/archive-hygiene.gradle and src/gradle/public-path-snapshot.gradle.

  • Produces: functional tests that execute real Gradle tasks and assert filesystem side effects.

  • Add an isolated functionalTest source set/task and its functionalTestImplementation gradleTestKit() dependency so Gradle's SLF4J provider cannot pollute ordinary tests.

  • Add a nested temporary archive fixture with root + family:module projects. Apply the production archive script, pre-create a stale traceable JAR and a nonmatching JAR, run :family:module:jar, verifyNoStaleTraceableJars, and cleanStaleTraceableJars, and assert exact preservation/deletion plus the full task-path diagnostic.

  • Add a temporary public-path fixture. Apply the production public-path script and assert missing/drifted snapshots are not written, the verifier rejects -PapprovePublicPathChange, and only the approved updater writes canonical content.

  • Confirm the contracts RED before the two production scripts exist. The first RED run used the ordinary test source set; after it exposed Gradle TestKit's SLF4J provider collision, move the contract and TestKit dependency to isolated functionalTest configurations and add their strict lock state.

Task 2: Separate Archive Verification from Cleanup

Files:

  • Create: src/gradle/archive-hygiene.gradle
  • Modify: src/build.gradle

Interfaces:

  • Produces: root tasks verifyNoStaleTraceableJars and cleanStaleTraceableJars with no dependency between them.

  • Move traceable archive matching/discovery and both root tasks into the applied script.

  • Remove the stale-deleting doFirst from every Jar task while retaining manifest metadata.

  • Apply the script before leaf check dependencies are configured; task actions discover leaf JAR tasks at execution time.

  • Explicitly declare both archive tasks configuration-cache incompatible because their actions inspect subproject task models.

  • Run the focused functional test and confirm archive cases are GREEN.

Task 3: Separate Public-Path Verification from Update

Files:

  • Create: src/gradle/public-path-snapshot.gradle
  • Modify: src/build.gradle
  • Modify: src/README.md
  • Modify: docs/security/public-paths-snapshot.txt

Interfaces:

  • Produces: read-only verifyPublicPathSnapshot and explicitly mutating updatePublicPathSnapshot.

  • Centralize canonical snapshot rendering in the script.

  • Make verification fail on missing env, missing snapshot, drift, and use of the approval property without any writes.

  • Make update require -PapprovePublicPathChange, create the parent directory, and write canonical content.

  • Replace documentation and snapshot instructions with updatePublicPathSnapshot -PapprovePublicPathChange.

  • Run the focused functional test and confirm all public-path cases are GREEN.

Task 4: Focused and Architecture Verification

Files: none beyond Tasks 1-3.

  • Run ./gradlew :app-bootstrap:functionalTest --tests '*BuildVerificationPurityContractTest' --console=plain.
  • Run ./gradlew :app-bootstrap:test --console=plain; 640 ordinary tests pass after TestKit isolation (6 skipped), alongside the 9 functional contracts.
  • Run ./gradlew :app-bootstrap:verifyDependencyLocks --console=plain.
  • Run ./gradlew :app-bootstrap:spotlessJavaCheck :app-bootstrap:checkstyleFunctionalTest :app-bootstrap:spotbugsFunctionalTest --console=plain.
  • Run ./gradlew verifyNoStaleTraceableJars verifyPublicPathSnapshot --console=plain and confirm both are read-only and pass on the current baseline.
  • Run ./gradlew verifyCleanArchitectureDependencies --console=plain.
  • Run git diff --check and record git status --short without staging or committing.