Four threads landing together — all driven by the audit J asked for before
production cutover.
(1) Gate 3b DECIDED: Option C (defer classifications). `BiometricCollection.classifications`
stays `Option<JSON> = None` in v1. `docs/specs/GATE_3B_DEEPFACE_DESIGN.md` status
flipped from "draft / awaits product" to DECIDED. Consent template + retention
schedule revised to remove all "automated facial-classification" / "deepface"
language so disclosed scope matches implemented scope.
(2) Endpoint-path drift reconciled across 3 docs. `PHASE_1_6_BIPA_GATES.md`,
`BIPA_DESTRUCTION_RUNBOOK.md`, and `biometric_retention_schedule_v1.md` had
references to legacy `/v1/identity/subjects/*` paths (proposed under a separate
identityd daemon, never shipped) — corrected to actual shipped routes
`/biometric/subject/*` (catalogd-local). Schema block in PHASE_1_6_BIPA_GATES
rewritten to reflect JSON `SubjectManifest.biometric_collection` substrate
(not the proposed Postgres `subjects` table).
(3) New operational artifacts:
- `scripts/staffing/verify_biometric_erasure.sh` — checks 4 things post-erasure
(manifest cleared, uploads dir empty, audit row matches, chain verified).
Smoke-tested live against WORKER-2.
- `scripts/staffing/biometric_destruction_report.sh` — monthly anonymized
destruction-event aggregation. Smoke-tested clean.
- `scripts/staffing/bundle_counsel_packet.sh` — tarballs the counsel-review
packet with per-file SHA-256 manifest.
- `docs/runbooks/LEGAL_AUDIT_KEY_ROTATION.md` — formal rotation procedure
operationalized after the 2026-05-05 /tmp wipe incident.
- `docs/counsel/COUNSEL_REVIEW_PACKET_2026-05-05.md` — cover note bundling
all eng-staged BIPA docs for counsel review with per-doc questions, sign-off
checklist, recommended review sequence.
(4) Double-upload file leak fixed in `crates/catalogd/src/biometric_endpoint.rs`.
`verify_biometric_erasure.sh` smoked WORKER-2 and surfaced a stranded photo
file. Investigation showed the file was 13-byte test-fixture bytes (zero PII,
no biometric content); audit timeline showed two consecutive uploads followed
by one erasure — the second upload had silently overwritten manifest.data_path,
orphaning the first file. Patched `process_upload` to refuse a second upload
with HTTP 409 + `error: "biometric_already_collected"` when
`biometric_collection.is_some()` on the manifest. Operator must explicitly
POST `/biometric/subject/{id}/erase` first.
Tests: new `second_upload_without_erase_returns_409` (asserts 409 + manifest
pointer unchanged + first file untouched on disk). Replaced
`repeated_uploads_grow_the_chain` with `upload_erase_upload_grows_the_chain_cleanly`
(covers the legitimate re-collection cycle: chain grows to 3 rows). Updated
`content_type_with_parameters_accepted` to use 2 distinct subjects (was
using 1 subject with 2 uploads to test ct parsing — would now 409).
22/22 biometric_endpoint tests + 59/59 catalogd lib tests green post-patch.
Production posture: gateway needs `cargo build --release -p gateway` +
`systemctl restart lakehouse.service` to pick up the new 409 in live traffic.
Counsel calendar is now the only remaining blocker for first real-photo intake.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
78 lines
2.4 KiB
Plaintext
78 lines
2.4 KiB
Plaintext
/target
|
|
*.swp
|
|
*.swo
|
|
.env
|
|
__pycache__/
|
|
*.pyc
|
|
|
|
# Headshot pool — binary face JPGs are fetched by scripts/staffing/fetch_face_pool.py
|
|
# (synthetic StyleGAN, ~580MB for 1000 faces). Manifest + fetch script are tracked.
|
|
data/headshots/face_*.jpg
|
|
data/headshots/_thumbs/
|
|
# ComfyUI on-demand generated portraits (per-worker unique). Cached on first
|
|
# request; fully regeneratable via /headshots/generate/:key.
|
|
data/headshots_gen/
|
|
|
|
# Runtime data — all regeneratable from inputs or accumulated by daemons.
|
|
# Anything under data/_<name>/ is internal state (auditor outputs, KB caches,
|
|
# pathway memory snapshots, HNSW trial results, etc.). Anything under
|
|
# data/datasets/ or data/vectors/ is generated by ingest/index pipelines.
|
|
data/_*/
|
|
data/lance/
|
|
data/datasets/
|
|
data/vectors/
|
|
data/demo/
|
|
data/evidence/
|
|
data/face_test/
|
|
data/headshots_role_pool/
|
|
data/icons_pool/
|
|
data/scored-runs/
|
|
data/workspaces/
|
|
data/catalog/
|
|
data/**/*.bak-*
|
|
data/**/*.pre-*-bak
|
|
|
|
# Logs
|
|
logs/
|
|
|
|
# Build artifacts
|
|
node_modules/
|
|
exports/
|
|
mcp-server/data/
|
|
|
|
# Per-run distillation reports (timestamp-named); keep the parent dir tracked
|
|
# via .gitkeep if needed but don't carry every batch's report set.
|
|
reports/distillation/[0-9]*/
|
|
reports/distillation/*-*-*-*-*/
|
|
|
|
# Test scratch — scratchpads, traces, sessions are regenerated each run.
|
|
# PRD/scenario fixtures stay tracked (they ARE the test).
|
|
tests/agent_test/_*
|
|
tests/agent_test/sessions/
|
|
tests/real-world/runs/
|
|
|
|
# BIPA-quarantined photo uploads — Phase 1.6 Gate 3a writes to
|
|
# data/biometric/uploads/<safe_id>/<ts>_<uuid>.<ext> with mode 0700/0600.
|
|
# This is regulated subject-of-record data and must NEVER enter git.
|
|
data/biometric/
|
|
|
|
# Local-only scrum review evidence. Per `feedback_audit_findings_log.md`
|
|
# scrum runs fold fixes into a batch commit; the verdict / disposition
|
|
# files stay local for forensics.
|
|
reports/scrum/
|
|
|
|
# Per-event biometric verification reports (timestamp-named, regenerated
|
|
# per `verify_biometric_erasure.sh` invocation). Source-of-truth is the
|
|
# audit chain itself; these reports are derived views.
|
|
reports/biometric/
|
|
|
|
# Counsel transmission tarballs + manifests are regenerated by
|
|
# `bundle_counsel_packet.sh` from the tracked `docs/counsel/` source.
|
|
# The bundle is transmittable, not source-of-truth.
|
|
reports/counsel/
|
|
|
|
# Local experiments scratchpad — per the "Test code in main is ACTIVELY
|
|
# being cleaned out" policy (commits 6aafd41 + f4ebd22), one-off
|
|
# experiments stay out of the tracked tree.
|
|
experiments/
|