Files
clean-architecture-backend-…/docs/superpowers/plans/2026-09-17-jpa-evidence-gradle-model-decoupling.md
T

103 lines
5.5 KiB
Markdown

# JPA Evidence Gradle Model Decoupling 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:** Remove execution-time Gradle `Project`/`Task`/`TaskState` access from JPA evidence generation without changing evidence semantics.
**Architecture:** A shared `JpaEvidenceExecutionService` consumes Gradle task-completion events for non-Test task claims. The JPA evidence plugin snapshots/configures JUnit result directories, provenance, environment/profile values, and dependency versions as typed task inputs. `GenerateJpaEvidenceManifestsTask` becomes a pure evidence assembler over those inputs plus filesystem/exec services.
**Tech Stack:** Java 21, Gradle 9 BuildService + Tooling Events, JUnit 6/TestKit, Jackson 3.
**Spec:** `docs/superpowers/specs/2026-09-17-jpa-evidence-gradle-model-decoupling-design.md`
## Global Constraints
- Preserve readiness-card schema and task names.
- Preserve JUnit XML as test evidence.
- Preserve task-claim meaning: only a successful producer task covers a task claim.
- Preserve evidence grade, blocker, hashing, prerequisite, output, candidate/R2 semantics.
- No execution-time `Project`, `Task`, or `TaskState` access in `GenerateJpaEvidenceManifestsTask`.
- Do not stage, commit, amend, reset, or push existing worktree changes.
---
### Task 1: Task completion evidence service
**Files:**
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceExecutionService.java`
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTaskOutcome.java`
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidenceExecutionServiceTest.java`
**Interfaces:**
- Produces: `JpaEvidenceExecutionService.outcome(String taskPath)` and `completedSuccessfully(String taskPath)`.
- Consumes: Gradle `TaskFinishEvent` via `OperationCompletionListener`.
- [ ] Write tests for success, failure, skipped, and unknown task paths.
- [ ] Verify tests fail because the service/model do not exist.
- [ ] Implement the typed outcome model and thread-safe service.
- [ ] Verify focused tests pass.
### Task 2: Typed JUnit evidence inputs
**Files:**
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTestResultLocator.java`
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTaskSupport.java`
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTestResultLocatorTest.java`
**Interfaces:**
- Consumes: `Map<String, String>` task-path to repository-relative/absolute JUnit XML directory.
- Produces: `JpaGeneratedTestResult read(String taskPath)` without `Project` or `Test`.
- [ ] Write a failing test that creates JUnit XML under a temporary directory and resolves it by task path.
- [ ] Implement file-based result lookup using `JUnitEvidenceReader`.
- [ ] Remove the `readJUnitResult(Project, Test)` helper once no caller remains.
- [ ] Verify focused tests pass.
### Task 3: Generator typed input surface
**Files:**
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/GenerateJpaEvidenceManifestsTask.java`
- Test: extend `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidencePluginTypeTest.java`
**Interfaces:**
- Add typed properties for profile/CI/artifact/topology/provenance/dependency versions/JUnit result directories.
- Add an internal/service reference to `JpaEvidenceExecutionService`.
- [ ] Add reflection/type tests asserting the new task properties exist and no generator source contains `getProject()` or `Task.getState()` usage.
- [ ] Verify the test fails against the current generator.
- [ ] Add the typed properties and service reference.
- [ ] Replace Project/Task/TaskState/configuration/extra-property reads with typed inputs/service lookups.
- [ ] Verify focused tests pass.
### Task 4: Plugin wiring
**Files:**
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidencePlugin.java`
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTaskSupport.java`
- Test: add `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidencePluginFunctionalTest.java`
**Interfaces:**
- Register shared execution service and task-completion listener.
- Configure generator typed inputs.
- Configure JUnit result-directory mapping for active readiness/support Test tasks.
- Preserve existing `dependsOn` producer graph.
- [ ] Write TestKit fixture asserting typed generator inputs and task wiring.
- [ ] Verify RED.
- [ ] Register/wire the service and all generator properties.
- [ ] Resolve dependency versions and release provenance during configuration/plugin wiring rather than task action.
- [ ] Verify TestKit GREEN.
### Task 5: Regression and Gradle 10-preparation verification
**Files:**
- Modify only if verification exposes a regression.
- [ ] Run `src/build-tools` full `check --warning-mode=fail`.
- [ ] Run root `verifyJpaReadinessRegistry verifyJpaReleaseGateTasks --warning-mode=fail`.
- [ ] Run `:adapter:outbound:persistence-jpa:check --warning-mode=fail`.
- [ ] Run candidate evidence generation with `--warning-mode=all`; verify there is no `Task.project`/execution-time project deprecation from JPA evidence tooling.
- [ ] Run adapter procedural-Groovy scan and confirm no regression.
- [ ] Run `git diff --check`.
- [ ] Record any environment-only Docker/Testcontainers limitation separately from code correctness.