7.6 KiB
7.6 KiB
Raw photo → live asset pipeline (quinn.www)
Grounded in:
codebase/@features/quinn-ai/engine/src/workers/photo-intake/index.ts(intake worker)codebase/@features/quinn-ai/backend-api/src/modules/skills/photo-intake.ts(orchestration skill)codebase/@features/image-protection/backend-api/src/pipeline.ts(protectPhotolayers)codebase/@features/image-protection/backend-api/src/watermark.ts(visible + forensic marks)
┌────────────────────────────────────────────────────────────────────────────┐
│ ① RAW PHOTO INGEST │
│ │
│ Quinn's phone ──iMessage (to self)──┐ │
│ (is_from_me, has_attachments) │ │
│ ▼ │
│ photo-intake WORKER (apricot) │
│ polls macsync.messages, pulls attachment bytes │
│ │ ┌───────────────────┐ │
│ Manual upload ──────────────────────┼─────────────│ users/transquinnftw│ │
│ (quinn-admin / quinn.my) │ │ /originals (masters)│ │
│ ▼ └───────────────────┘ │
│ POST /api/skills/process-uploaded-photo (quinn-ai :3028) │
└───────────────────────────────────────┬──────────────────────────────────────┘
│ orchestrates 4 admin-backend calls
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ ② UPLOAD POST /admin/photos/upload │
│ → writes raw into the protection INPUT POOL, per platform subdir │
└───────────────────────────────────────┬──────────────────────────────────────┘
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ ③ PROTECT POST /admin/photo-protection/run → protectPhoto() │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ L1 Forensic watermark invisible ±1 spread-spectrum, seeded by │ │
│ │ sha256("transquinnftw.com:{file}") │ │
│ │ L2 Face detection SCRFD bbox/landmarks │ │
│ │ L4 Identity cloaking PGD vs ArcFace, eps=0.03 (runs first) │ │
│ │ L3 Detection evasion PGD vs SCRFD, eps=0.08 │ │
│ │ L5 Landmark obfuscation │ │
│ │ L6 VISIBLE WATERMARK ◀── transquinnftw.com SVG composite │ │
│ │ ★ THIS is the layer the Kuromi techno mark replaces ★ │ │
│ │ L7 SSIM gate abort if SSIM < 0.75 (quality guard) │ │
│ │ L8 Finalize JPEG (mozjpeg) + WebP │ │
│ │ L9 Adversary view saliency / perturbation / detector maps │ │
│ │ → public/photos/adversary/{file}/ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ ④ POLL /admin/photo-protection/runs/:id until status = done │
└───────────────────────────────────────┬──────────────────────────────────────┘
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ ⑤ DEPLOY POST /admin/photo-protection/deploy │
│ rsync protected JPEG+WebP (+ manifest.json) to each configured │
│ deploy target (name → rsync destination URL) │
└───────────────────────────────────────┬──────────────────────────────────────┘
▼
┌────────────────────────────────────────────────────────────────────────────┐
│ ⑥ LIVE ASSET │
│ quinn-vps : deployments/@domains/quinn.www/root/public/photos/ │
│ ├── {name}.jpeg / .webp ← gallery <picture> sources │
│ ├── manifest.json ← dims/sizes the gallery reads │
│ └── page-illustrations.json ← decorative section graphics │
│ │
│ Served on transquinnftw.com (website) + platform ad surfaces │
└──────────────────────────────────────────────────────────────────────────────┘
Where the Kuromi watermark work fits
Two paths, not mutually exclusive:
-
Backfill (this task):
tooling/scripts/watermark/batch.pyre-marks the existing library from CLEAN sources →public/photos-watermarked/. One-off correction of the already-deployed set (which carries the old white L6 mark). -
Pipeline integration (the durable fix): port the chosen Kuromi style into L6 (
buildVisibleWatermarkSvginwatermark.ts) so every FUTURE intake photo gets the new mark automatically — no manual re-run. Note: L6 currently composites an SVG viasharp; the Pillow renderer here would either be reimplemented as SVG or invoked as a sidecar. Decide after Quinn locks the look (placement + opacity).