- 12-vector TDD suite, 4 source gates + bundle gate + 2 live probes, the 0/1/2 exit contract, and docs/PRIVACY-AUDIT.md signed-record scaffold - PRIVACY AUDIT CLEAN — 5 gate(s) passed, 0 violations on the audited tree - baselines intact: bot 125/125, web 165/165
10 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-hardening-private-launch | 03 | testing |
|
|
|
|
|
|
|
|
|
9min | 2026-10-24 |
Phase 7 Plan 03: Consolidated privacy audit + signed record Summary
One consolidated npm run privacy-audit CLI — 5 static gates over all five src trees + the production bundle, 2 credential-gated live probes, honest 0/1/2 exit codes — plus docs/PRIVACY-AUDIT.md, the signed audit record citing the real run's evidence (D-01/D-02).
Performance
- Duration: 9 min (20:32Z → 20:41Z)
- Started: 2026-10-24T20:32:07Z
- Completed: 2026-10-24T20:41:00Z
- Tasks: 3 (TDD RED→GREEN)
- Files modified: 7 (6 created, 1 modified)
Accomplishments
- The repo's gate lineage consolidated, not duplicated: the phase-3 memory-only law, the PG1 same-line TTL law, the D-14 category-only log law, and the bundle laws are now enforced REPO-WIDE by one tool — the existing unit-level suites stay as the pins
- All 5 static gates PASS on the audited tree (commit
9c55e9a): 72 files scanned, 4 KV writes all TTL-named, 28 log call sites category-verified, host inventories printed (source + bundle), ZERO analytics/beacon/crypto/storage tokens inweb/dist docs/PRIVACY-AUDIT.mdcarries the ACTUAL evidence strings from the run, the four KV-family storage inventory, the log vocabulary, the runtime-network inventory with D-02's zero-telemetry posture, and the blank human signature block (D-09's launch gate signs it)- Live probes verified honest-by-construction: without credentials both return notRun and the CLI exits 2 — never a silent pass (T-07-16)
task Commits
Each task was committed atomically (TDD: RED gate commit → GREEN feat commits):
- task 1: the source-gates library —
87fcb28(test: RED — 12-vector suite) +430993b(feat) - task 2: bundle-gates + cloudflare-probes —
b959e23(feat) - task 3: the CLI + npm script + signed record —
9c55e9a(feat) +8229e36(docs)
Files Created/Modified
scripts/lib/source-gates.mjs— runStorageGate / runKvTtlGate / runLogVocabularyGate / runRuntimeHostGate over web/bot/routing/search/theme srcscripts/lib/bundle-gates.mjs— runBundleTelemetryGate (PRODUCTIONweb/distONLY;dist-harnessforbidden)scripts/lib/cloudflare-probes.mjs— runKvExpiryProbe / runAssetHeaderProbe / probeUnavailable (namespace id read frombot/wrangler.jsoncat runtime)scripts/privacy-audit.mjs— the orchestrator: Pattern-4 ordering, per-gate evidence lines, CLEAN/FAILED/NOT RUN summaries, process.exit 0/1/2scripts/test/privacy-audit.test.mjs— the 12-vector TDD suite (SA1-5, BG1-2, CP1-2, AU1-3)package.json— root"privacy-audit": "node scripts/privacy-audit.mjs"docs/PRIVACY-AUDIT.md— the signed audit record (D-01)
Decisions Made
- Bundle static-text adjudication: the plan's 2-host allowlist fails on MapLibre's own embedded attribution/diagnostic URLs in the shipped bundle (they are library constants and our dataset's ODbL metadata — never fetched). Followed the repo's own "Scope adjudications (documented, deliberate)" precedent (theme/scripts/audit.mjs): an explicitly enumerated static-text class, each host with its reason, full inventory printed as evidence. Any host outside both lists fails.
- Header probe honesty: the first live run exposed the probe interpreting a 404 as "no cache-control" — the probe now reads HTTP status first and treats origin/build mismatch as deployment drift (exit-2 class). The immutable
/assets/*policy ASSERTION belongs to 07-04's budget-audit (its_headersfile); this probe quotes, never interprets. - Test injectability: gates accept an opts-only roots/dist override (production callers pass nothing), letting the suite prove each gate FAILS on synthetic violations in temp fixtures.
- cwd-independent root with the
PRIVACY_AUDIT_ROOToverride — a stray subdirectory run must not scan the wrong tree and false-pass.
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Asset-header probe misread a stale-deploy 404 as a cache violation
- Found during: task 3 (first
--liverun) - Issue: the probe fetched the local dist's hashed asset from the deployed origin without checking HTTP status; a 404 printed "no cache-control header observed" and FAILED the gate with
undefined violation(s)(also a${violations.length}bug on a number) - Fix: status line read before header interpretation; non-2xx = notRun (deployment drift) with observed headers carried in evidence; the count bug fixed
- Files modified: scripts/lib/cloudflare-probes.mjs
- Verification:
npm run privacy-audit -- --livenow exits 2 withPRIVACY AUDIT NOT RUN — deployment drift …; CP2 vector pins the shape - Committed in: b959e23/9c55e9a follow-ups (folded into the task-2/3 commits)
Total deviations: 1 auto-fixed (1 bug) Impact on plan: The fix makes the live probe's honesty contract hold end-to-end. The live legs were recorded NOT RUN in docs/PRIVACY-AUDIT.md — honest, exit-2 class, re-run at the launch gate.
Issues Encountered
- The deployed Worker (
araharah-bot.workers.dev) serves a bundle older than the currentweb/dist(its hashed asset 404s) — correctly reported as deployment drift by the probe; a redeploy (07-04/07-06) plus shipped_headerswill turn the live legs green.
Known Stubs
None — every gate/probe is fully wired; no placeholder data flows anywhere.
User Setup Required
None — no external service configuration required. (The --live probes need CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID in the environment; absent credentials degrade to exit 2 by design, never a pass.)
Next Phase Readiness
- 07-04 (budget-audit) re-runs the live header probe against a deployed build carrying its
_headerspolicy — the two plans share the live-probe surface - 07-06 (launch gate) signs
docs/PRIVACY-AUDIT.md's signature block as the privacy-audit checklist leg; the--livere-run protocol is documented in the record - Baselines intact: bot 125/125, web 165/165;
npm run privacy-auditexits 0 (PRIVACY AUDIT CLEAN — 5 gate(s) passed, 0 violations)
Phase: 07-hardening-private-launch Completed: 2026-10-24
Self-Check: PASSED
All 7 created files verified on disk; all 5 task commits verified in git log
(87fcb28 test-RED, 430993b, b959e23, 9c55e9a, 8229e36). STATE.md and
ROADMAP.md untouched (orchestrator-owned).