Files
tech-log-backend/docs/superpowers/specs/2026-07-25-harness-free-quality-security-ci-design.md
T

98 lines
5.7 KiB
Markdown

# Harness-Free Quality and Security CI Design
- **Date:** 2026-07-25
- **Status:** Approved Mode B reconstruction
- **Scope:** Repository-internal quality, dependency-vulnerability, and link-check controls
## Decision and provenance
Mode B reconstructs observable CI contracts from the current Gradle build, active documentation,
and the incomplete `/home/donghyeon/dev/ca-tmpl` checkout. The candidate checkout is evidence, not
an authoritative or byte-identical restoration source. Its useful policy is adapted to the current
`main` branch and current tasks; stale `master`, feature-branch ownership, and absent workflow
claims are removed.
`.github/workflows/` is the canonical workflow path. No `.gitea/workflows` shadow is created. The
origin is Gitea, but server-side Actions is externally disabled, so these files define repository
controls without claiming that remote jobs currently execute.
Every external `uses:` reference is pinned to a verified 40-character commit SHA. Its immutable
release tag remains beside the SHA as an inline review label; moving major-version tags are not an
execution authority.
## Scope boundary
This slice owns:
- pinned Java tool evidence and text/binary normalization;
- structured Trivy suppression governance and CODEOWNERS review surfaces;
- the quality-gate matrix and its drift verifier;
- quality, filesystem vulnerability, and documentation-link workflows;
- human-readable dependency severity, suppression, network, and forge-compatibility policy.
The development harness remains excluded: no `.harness`, `.agents`, `.claude`, or `.codex`
runtime is reconstructed. Build/release supply-chain, tag release, image scanning, signing,
provenance, SBOM, retention, and Docker root-context work belongs to the later Phase A2 slice and
is not represented as a present workflow job.
## Considered approaches
1. Copy the candidate files unchanged. Rejected because they target `master`, refer to missing
supply-chain scripts/jobs, and describe obsolete branch ownership.
2. Reconstruct a minimal current control plane from repository evidence. Selected because every
gate can be checked against a present Gradle task, test, script, or workflow job.
3. Merge all checks into one workflow. Rejected because GitHub-only dependency APIs need forge
guards, scheduled vulnerability scans have different triggers, and link checks are path-scoped.
## Components and gate flow
`ci-quality-gates.yml` runs three required jobs: the aggregate Gradle quality suite, the sample-off
axis, and gate-matrix lint. Before Java setup or Gradle, the quality job requires
`docs/security/public-paths-snapshot.txt` to be committed and non-empty. The worktree now contains
the canonical baseline for `/api/healthcheck`; because agents do not stage or commit, a human must
track and commit it before CI's `git ls-files` precondition can pass. This prevents
`verifyPublicPathSnapshot` from creating a first-run baseline inside CI and passing without
comparison.
`release-gate` uses `if: always()` and accepts only `success` from those three jobs; the advisory
quarantine job is deliberately outside its `needs`.
The quality aggregate runs `check`, `verifyPublicPathSnapshot`, and `verifyDependencyLocks`
explicitly. `check` already pulls in Clean Architecture dependency enforcement, environment/readme
drift checks, Trivy-ignore governance, format/static analysis, normal tests, and quarantine sunset.
`dependency-vulnerability.yml` keeps GitHub Dependency Graph operations behind
`github.server_url == 'https://github.com'`. Platform-neutral `trivy-fs` runs for PR, `main` push,
daily schedule, and manual dispatch. Trivy and jq install into `${RUNNER_TEMP}` and expose their
directories through `${GITHUB_PATH}`. Every Trivy scan names `.trivyignore.yaml`; High/Critical and
KEV matches block, while Medium/Low only report. The KEV gate first rejects blank metadata,
non-positive/non-integral or mismatched counts, empty arrays, invalid CVE identifiers, and duplicate
identifiers. It separately rejects malformed/empty Trivy JSON before extracting candidate IDs.
Dependency review reports through its check only and does not request permission to write a PR
summary comment. Vulnerability DB, tool release, malformed/empty KEV or Trivy data, and KEV feed
network failures remain blocking unless internal mirrors are configured.
`link-check.yml` is path-scoped for PR and `main` push, and remains manually runnable.
## Drift verification and failure behavior
`.github/ci-gate-matrix.yml` lists only current mechanisms/jobs. The verifier resolves the
repository root from its own physical location, rejects incomplete/duplicate records, and checks
referenced Gradle custom tasks, plugins, contract-test files, workflow files, and job IDs.
Delegated-pending is supported only when a row is explicitly marked; no absent supply-chain job is
invented in this slice.
The CI release fan-in fails for failed, cancelled, or unexpectedly skipped required jobs. Trivy's
KEV feed cross-check is fail-closed. GitHub-only jobs may skip by their explicit forge/event
conditions and are not dependencies of the quality release fan-in.
## Verification
Acceptance requires the prescribed RED for the absent `.trivyignore.yaml`, GREEN
`verifyTrivyignore`, proof that the snapshot precondition rejects missing, empty, or untracked
baselines, and a human-tracked canonical snapshot for CI. It also requires strict synthetic KEV
catalog negative/positive cases, shell syntax and matrix verification, workflow YAML/static checks,
evidence that `main` is the only active branch trigger, Trivy ignorefile coverage, exact release
fan-in, absence of harness/Gitea shadow workflows, `git diff --check`, and reviewed working-tree
status. Network Trivy scans are intentionally not run locally.