Phase 16: CI dependency audit & security checks #15
@@ -329,7 +329,7 @@ Plans:
|
||||
**Wave 1**
|
||||
|
||||
- [x] 16-01-PLAN.md — Image-hygiene runtime: bake NODE_ENV=production + boot-time refuse-to-boot guard (IMG-01)
|
||||
- [ ] 16-02-PLAN.md — pnpm audit gate + waiver allowlist + advisory-only tiered outdated report (DEP-01, DEP-02)
|
||||
- [x] 16-02-PLAN.md — pnpm audit gate + waiver allowlist + advisory-only tiered outdated report (DEP-01, DEP-02)
|
||||
- [ ] 16-03-PLAN.md — Fold eslint-plugin-security into the lint gate as blocking errors + triage (SEC-02)
|
||||
- [ ] 16-04-PLAN.md — gitleaks config + full-history baseline + .dockerignore (SEC-01, IMG-02)
|
||||
|
||||
@@ -359,7 +359,7 @@ Plans:
|
||||
| 13. Real Lint Gate (ESLint) | v1.1 | 3/3 | Complete | 2026-06-12 |
|
||||
| 14. Desktop E2E Coverage | v1.1 | 1/1 | Complete | 2026-06-12 |
|
||||
| 15. Doc-Only CI Skip + MD Lint | v1.1 | 3/3 | Complete | 2026-06-12 |
|
||||
| 16. CI Dep Audit, Sec & Img Hyg | v1.1 | 1/6 | In Progress| |
|
||||
| 16. CI Dep Audit, Sec & Img Hyg | v1.1 | 2/6 | In Progress| |
|
||||
|
||||
## Backlog
|
||||
|
||||
@@ -367,7 +367,7 @@ Plans:
|
||||
|
||||
**Goal:** [Captured for future planning] Abstract the calendar backend behind a provider interface so Fastmail/CalDAV is one implementation among potentially many. Shipping with a single provider is fine, but the broker, sync, and event-expansion layers should be structured so additional providers (e.g. other CalDAV hosts, Google Calendar, generic ICS feeds) can be added without rework. Captures the "provider" seam as an explicit architectural concern.
|
||||
**Requirements:** TBD
|
||||
**Plans:** 1/6 plans executed
|
||||
**Plans:** 2/6 plans executed
|
||||
|
||||
Plans:
|
||||
|
||||
|
||||
+5
-4
@@ -4,13 +4,13 @@ milestone: v1.1
|
||||
milestone_name: Operability & Polish
|
||||
status: executing
|
||||
stopped_at: Completed 16-01-PLAN.md
|
||||
last_updated: "2026-06-13T09:15:26.256Z"
|
||||
last_updated: "2026-06-13T09:20:23.640Z"
|
||||
last_activity: 2026-06-13 -- Phase 16 execution started
|
||||
progress:
|
||||
total_phases: 19
|
||||
completed_phases: 6
|
||||
total_plans: 23
|
||||
completed_plans: 18
|
||||
completed_plans: 19
|
||||
percent: 32
|
||||
---
|
||||
|
||||
@@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-06-10)
|
||||
## Current Position
|
||||
|
||||
Phase: 16 (ci-dependency-audit-and-security-checks) — EXECUTING
|
||||
Plan: 2 of 6
|
||||
Plan: 3 of 6
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-06-13 -- Phase 16 execution started
|
||||
|
||||
@@ -104,6 +104,7 @@ _Updated after each plan completion_
|
||||
| Phase 13-real-lint-gate-eslint P03 | 10 | 3 tasks | 399 files |
|
||||
| Phase 09-faster-write-back P01 | 341 | 3 tasks | 3 files |
|
||||
| Phase 16 P01 | 188 | 3 tasks | 4 files |
|
||||
| Phase 16-ci-dependency-audit-and-security-checks P02 | 25 | 3 tasks | 5 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@@ -231,7 +232,7 @@ Recent decisions affecting current work:
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-06-13T09:15:26.245Z
|
||||
Last session: 2026-06-13T09:20:23.627Z
|
||||
Stopped at: Completed 16-01-PLAN.md
|
||||
Resume file: None
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
phase: 16-ci-dependency-audit-and-security-checks
|
||||
plan: "02"
|
||||
subsystem: ci-security
|
||||
tags: [dependency-audit, pnpm-audit, pnpm-outdated, allowlist, tdd]
|
||||
dependency_graph:
|
||||
requires: []
|
||||
provides: [scripts/check-audit.mjs, scripts/audit-allowlist.json, scripts/check-outdated.mjs, scripts/outdated-pins.json]
|
||||
affects: [16-05-ci-security-job]
|
||||
tech_stack:
|
||||
added: []
|
||||
patterns: [node-wrapper-script, tdd-red-green, audit-allowlist-pattern]
|
||||
key_files:
|
||||
created:
|
||||
- scripts/check-audit.mjs
|
||||
- scripts/audit-allowlist.json
|
||||
- scripts/check-outdated.mjs
|
||||
- scripts/outdated-pins.json
|
||||
- scripts/__tests__/check-audit.test.mjs
|
||||
modified: []
|
||||
decisions:
|
||||
- "D-04/D-05: Audit wrapper uses committed allowlist (audit-allowlist.json) with reason+reviewer+expiry per GHSA; Option B over native pnpm.auditConfig.ignoreGhsas (no accountability metadata in native approach)"
|
||||
- "D-06: check-outdated.mjs always exits 0; tiered report never gates"
|
||||
- "Pitfall 1 honored: pnpm audit --json with NO --audit-level flag"
|
||||
- "TDD gate: test(16-02) RED commit precedes feat(16-02) GREEN commit"
|
||||
metrics:
|
||||
duration: 25
|
||||
completed: "2026-06-13"
|
||||
tasks: 3
|
||||
files: 5
|
||||
---
|
||||
|
||||
# Phase 16 Plan 02: Dependency Audit Gate + Outdated Report Summary
|
||||
|
||||
**One-liner:** pnpm audit blocking wrapper with committed GHSA allowlist (esbuild waiver pre-seeded) plus tiered outdated report — both as standalone Node.js scripts, TDD-verified.
|
||||
|
||||
## What Was Built
|
||||
|
||||
### Task 1 — Audit allowlist + pin reasons (chore, `0f101bd`)
|
||||
|
||||
- `scripts/audit-allowlist.json`: committed GHSA waiver map. Seeded with `GHSA-gv7w-rqvm-qjhr` (esbuild High advisory, transitive dev-only via drizzle-kit/vitest/vite, not in production image). Each entry carries `reason`, `reviewer`, and `expires` fields for auditability.
|
||||
- `scripts/outdated-pins.json`: flat package→reason map for four intentional pins: eslint (ESLint 10 breaks eslint-plugin-react), @eslint/js (same), zod (v4 breaking API), @types/node (Node 22 LTS types).
|
||||
|
||||
### Task 2 — check-audit.mjs blocking wrapper, TDD (`7ac8b19` RED → `6eb5107` GREEN)
|
||||
|
||||
- `scripts/check-audit.mjs`: exports two pure functions (`selectBlocking`, `partitionAdvisories`) for unit testing. Main body runs only when invoked directly (import.meta.url guard). Uses `pnpm audit --json` with no `--audit-level` (Pitfall 1 honored). Exits 1 on unwaived High/Critical; exits 0 with advisory report for moderate/low.
|
||||
- `scripts/__tests__/check-audit.test.mjs`: 5 cases via `node:test` + `node:assert` (no extra deps). Covers: unwaived High → blocking; waived High → not blocking; moderate/low only → not blocking; no advisories → not blocking; mixed → correct partition.
|
||||
- All 5 tests green.
|
||||
|
||||
### Task 3 — check-outdated.mjs tiered report (`baf2e3a`)
|
||||
|
||||
- `scripts/check-outdated.mjs`: classifies outdated packages into four tiers (AUDIT-ADVISORY > MAJOR-BEHIND-INTENTIONAL > MAJOR-BEHIND-UNPINNED > ROUTINE-DRIFT). Cross-checks `pnpm audit --json` to surface pinned-but-vulnerable packages under AUDIT-ADVISORY. Reads `outdated-pins.json` to label intentional pins with their reason. Always `process.exit(0)` — never gates (D-06).
|
||||
- Live run output: eslint/@eslint/js/zod/@types/node correctly under INTENTIONAL, @vitejs/plugin-react/jsdom/typescript under UNPINNED, hono/mysql2/@types/react under ROUTINE-DRIFT.
|
||||
|
||||
## Verification Results
|
||||
|
||||
- `node --test scripts/__tests__/check-audit.test.mjs` → 5/5 pass
|
||||
- `node scripts/check-outdated.mjs` → exit 0, tiered report printed
|
||||
- `node -e "require('./scripts/audit-allowlist.json')['GHSA-gv7w-rqvm-qjhr']"` → defined
|
||||
- `grep "execSync" scripts/check-audit.mjs` → `pnpm audit --json` (no `--audit-level`)
|
||||
- `grep -c "process.exit(0)" scripts/check-outdated.mjs` → 1
|
||||
- `grep "process.exit(1)" scripts/check-outdated.mjs` → absent
|
||||
|
||||
## TDD Gate Compliance
|
||||
|
||||
| Gate | Commit | Message |
|
||||
|------|--------|---------|
|
||||
| RED | 7ac8b19 | test(16-02): add failing tests for check-audit.mjs filter logic |
|
||||
| GREEN | 6eb5107 | feat(16-02): add check-audit.mjs blocking wrapper + unit tests |
|
||||
|
||||
TDD gate sequence correct: test commit precedes implementation commit.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None — plan executed exactly as written.
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None. All scripts are fully functional with live data.
|
||||
|
||||
## Threat Flags
|
||||
|
||||
No new threat surface introduced. Files created are scripts (no network endpoints, no auth paths, no schema changes).
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- `scripts/check-audit.mjs` — exists ✓
|
||||
- `scripts/audit-allowlist.json` — exists ✓ (GHSA-gv7w-rqvm-qjhr present)
|
||||
- `scripts/check-outdated.mjs` — exists ✓
|
||||
- `scripts/outdated-pins.json` — exists ✓
|
||||
- `scripts/__tests__/check-audit.test.mjs` — exists ✓
|
||||
- Commits 0f101bd, 7ac8b19, 6eb5107, baf2e3a — all present in git log ✓
|
||||
Reference in New Issue
Block a user