docs(16): capture phase context
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# Phase 16: CI Dependency Audit, Security Checks & Image Hygiene - Discussion Log
|
||||
|
||||
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
||||
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
||||
|
||||
**Date:** 2026-06-12
|
||||
**Phase:** 16-ci-dependency-audit-and-security-checks
|
||||
**Areas discussed:** Security-check baseline, Audit + outdated policy, Image-hygiene enforcement (999.17), Gating & noise posture
|
||||
|
||||
---
|
||||
|
||||
## Security-Check Baseline
|
||||
|
||||
### Which checks form the baseline (multiSelect)
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Secret scan on diff | gitleaks/trufflehog scans the PR diff for committed secrets | ✓ |
|
||||
| Static security lint | eslint-plugin-security or CodeQL | ✓ |
|
||||
| Trivy image scan | scan built production image for OS/package CVEs | ✗ (later dropped) |
|
||||
| Dependency-review action | GitHub's PR action — depends on GitHub API, not on Gitea | |
|
||||
|
||||
**User's choice:** Secret scan + static security lint + (initially) trivy — then dropped trivy in the follow-up.
|
||||
|
||||
### Secret-scan scope
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Diff + one full-history scan | per-PR diff + a one-time full-history baseline | ✓ |
|
||||
| PR diff only | only changed commits | |
|
||||
| Full tree every run | whole repo every PR | |
|
||||
|
||||
### Trivy gate
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Publish-time, advisory | scan image, never block | |
|
||||
| Publish-time, block on CRITICAL | fail publish on CRITICAL | |
|
||||
| Per-PR (build image in PR) | earliest feedback | |
|
||||
|
||||
**User's choice:** "Drop Trivy for now. I don't want it in the backlog, but it can be some future thing if we need it." → Trivy removed from scope entirely.
|
||||
|
||||
### Static security lint severity
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Warn (advisory) | surfaced but non-blocking | |
|
||||
| Error (blocking) | fails the lint gate | ✓ |
|
||||
|
||||
**Notes:** User accepts that blocking eslint-plugin-security will require triaging/disabling existing heuristic findings to reach green.
|
||||
|
||||
---
|
||||
|
||||
## Audit + Outdated Policy
|
||||
|
||||
### pnpm audit severity threshold
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| High + Critical | fail on high/critical | ✓ |
|
||||
| Critical only | fail only on critical | |
|
||||
| Moderate+ | fail on moderate and above | |
|
||||
|
||||
### Waiver mechanism
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Allowlist file in repo | committed advisory-ID list + reason + reviewer | ✓ |
|
||||
| pnpm overrides / config | auditConfig.ignore* in package.json | |
|
||||
| No waiver mechanism yet | deal with it if/when it blocks | |
|
||||
|
||||
### Outdated reporting vs intentional pins
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Advisory PR comment, never gates | pnpm outdated -r as PR comment | |
|
||||
| Advisory, job-log only | print to job log | |
|
||||
| Skip outdated entirely | rely on audit only | |
|
||||
|
||||
**User's choice:** Deferred to researcher (OQ-01). "Version pins are fine but if there's an issue with them or if they are too far behind there should be a balance here." Outcome locked: advisory, never gates; researcher designs the "dangerously behind / pinned-version-has-advisory" flagging.
|
||||
|
||||
---
|
||||
|
||||
## Image-Hygiene Enforcement (999.17)
|
||||
|
||||
### Enforcement mechanism (multiSelect)
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Bake NODE_ENV=production into image | engages devBypass hard guard in shipped image | ✓ |
|
||||
| Boot-time refuse-to-boot | throw + non-zero exit on prod + dev-bypass | ✓ |
|
||||
| Build-time abort | fail build/publish on dev target/arg | |
|
||||
|
||||
**Notes:** publish.yml already pins `--target production`; the static CI assertion covers "stays that way."
|
||||
|
||||
### CI assertion depth
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Static + boot smoke | .dockerignore + --target assertion + run image with dangerous combo, assert refuses to boot | ✓ |
|
||||
| Full filesystem forensics | export image fs, grep for secrets/seed/.git | |
|
||||
| Static checks only | no container built/run | |
|
||||
|
||||
### .dockerignore scope
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Secrets + dev + bulk | .env*, seed-credential.mjs, .git, node_modules, dist, tests, e2e, .planning, *.sql, playwright artifacts | ✓ |
|
||||
| Secrets-only minimal | only secret/seed/data files | |
|
||||
| Researcher proposes the list | capture intent, enumerate later | |
|
||||
|
||||
---
|
||||
|
||||
## Gating & Noise Posture
|
||||
|
||||
### Job layout
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| New 'security' job, parallel | gitleaks+audit+outdated parallel to fast-checks | |
|
||||
| Fold into fast-checks | steps in existing job | |
|
||||
| Researcher decides layout | pick against runner constraints | ✓ |
|
||||
|
||||
**Notes:** Recommendation surfaced (dedicated parallel `security` job) but final decomposition left to researcher/planner.
|
||||
|
||||
### Doc-only PR behavior
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Secret scan always; audit/outdated code-only | gitleaks universal, audit/outdated behind changes filter | ✓ |
|
||||
| All new checks code-only | whole security job skips doc-only | |
|
||||
| All new checks always run | run on every PR | |
|
||||
|
||||
### Result surfacing
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Job-log summary only | advisory output to job log | ✓ |
|
||||
| PR comment via Gitea API | step posts/updates a PR comment | |
|
||||
|
||||
### Renovate / Dependabot
|
||||
|
||||
| Option | Description | Selected |
|
||||
|--------|-------------|----------|
|
||||
| Defer | out of scope; capture as deferred | ✓ |
|
||||
| In scope | add upgrade-bot config this phase | |
|
||||
|
||||
---
|
||||
|
||||
## Claude's Discretion
|
||||
|
||||
- Job decomposition for the new PR-time checks (D-15) — researcher/planner.
|
||||
- Exact secret-scan tool (gitleaks vs trufflehog) and exact `.dockerignore` line list — researcher confirms.
|
||||
|
||||
## Deferred Ideas
|
||||
|
||||
- Renovate / Dependabot automated dependency upgrades — future phase/backlog.
|
||||
- Trivy / image CVE scanning — dropped, not backlogged (revisit only if needed).
|
||||
- PR-comment surfacing of advisory results — deferred in favor of job-log-only.
|
||||
- Stale pending todo `2026-06-10-gitea-ci-regression-and-docker-publish.md` — already delivered in Phase 8; should be archived.
|
||||
Reference in New Issue
Block a user