98 lines
5.7 KiB
Markdown
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.
|