# 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.