Pier Log Flow — Phase 2 Cutover

The PIN-based pier log upload system is retired. Crews now upload at unlikely.pl by entering the permit number + customer number from the pier-log packet, photographing the log, and confirming the parsed count. Each pier type (push / slab / helical) uploads once when ALL of that type is installed (multi-day installs roll up). The cert-validate gate is now authoritative — a project with UND-PUSH/SLAB/HELI in scope will not certify until uploads cover the SoW. Legacy projects with pier_log.json already on disk and no new-style session continue to legacy-pass.

Connections

  • replaces: pier-log-phase-1 (permissive WARN gate + 4-digit PIN URL)
  • gates: cert-validate-service Check 5 (now FAIL not WARN when uploads short of SoW)
  • escalates via: pierlog-escalation-service (escalate_missing_pierlogs cron at 7:15 AM ET, SMS via Telnyx to config.BRANCH_SCHEDULERS)
  • depends on: pier-log-upload-service (new-style session model, _status.json-free atomic disk model, SHA-256 dedup, supersede-via-confirm)
  • depends on: permit-lookup-service (Step 1 conjunction match: permit + customer; Step 2 fuzzy address fallback within customer’s projects)
  • consumes: unlikely.pl-domain via Caddyfile (root → /pierlog/log; /pierlog/* → reverse_proxy 8000; legacy /{4-digit} block REMOVED)
  • produces: rows in [[pierlog_discrepancies]] (Supabase) when uploaded count ≠ SoW target — feeds an office portal queue (UI not yet shipped)
  • file storage: /data/projects/{ss_id}/PIERLOGS/ (was /DRIVELOGS/); project_files.category = 'PIERLOGS' (was 'DRIVELOGS'); driven by config.PIERLOG_DIR_NAME
  • bilingual crew handout: pier-log-qr-sticker-v1 in assets/stickers/

Rollout (2026-04-28)

  • Phase 1 (session 48, 2026-04-26): full new-style upload code shipped, gate ran in PERMISSIVE mode; legacy two-tier escalation still in place; PIN minting still active in daily_schedule. Zero observable behavior change.
  • Bucket A (end of session 48): morning escalation cron registered (7:15 AM ET); daily_schedule PIN minting removed; WhatsApp formatter switched per-stop pier-log line from unlikely.pl/{pin} to static unlikely.pl gated on has_und.
  • Bucket B (2026-04-28, this cutover):
    • cert-validate Check 5 flipped from WARN → FAIL (commit 1a82a65)
    • 2,761 disk dirs renamed DRIVELOGSPIERLOGS (~68 sec API downtime)
    • 254 project_files.category rows updated DRIVELOGSPIERLOGS
    • config.PIERLOG_DIR_NAME flipped from "DRIVELOGS""PIERLOGS" (commit f51d862)
    • services/pierlog_escalation.py line 64 hardcoded "DRIVELOGS" replaced with config.PIERLOG_DIR_NAME (commit f51d862)
    • unlikely.pl/{4-digit} Caddy block dropped; legacy PIN URLs now return 404 (Caddyfile, not git-tracked)
    • JES scheduler email sent (Gmail msg id 19dd486ba534d8b1) with bilingual EN+ES PDF handout attached

SoW data hygiene (gate prerequisite)

  • Jacob audited 84 SoW pier-quality flags (CSV emailed 2026-04-26) before cutover. 67 confirmed-green; 7 legacy projects with no UND SOW + pier log on disk noted as “ignore”; 11 escalations.
  • 60 SOW lines backfilled as_built_qty + inspected=Inspected in this session (audit_backfill_2026-04-28).
  • 7 legacy pier_log_on_disk_but_no_und_sow projects: triage_notes added explaining intentional non-backfill; blkhse.44927 advanced from Ready for Cert → Certified to align state.
  • 3 escalations addressed: 12 D Street NW cert regenerated with corrected pier 7+8 data; 2681 Cunningham Hole flagged PPDR for Stephaney; 41 West Trail (CT) flagged PPDR blocked on Kai photos. Two remaining (Scotts Manor + Oak Lane) await Dustin review.

Operational notes

  • Branch scheduler SMS routing: BAL → Julia (+1 443-452-3353), MAN → Anna (+1 210-862-0040), NHAV → Kai (+1 475-414-1809), RIC → None (falls back to Dustin), UPR → None.
  • The escalation message is sent direct via Telnyx /v2/messages (not the portal-user-shaped notification_router._send_sms) since branch scheduler phones are not portal users.
  • Pre-existing tech debt resolved: qrcode>=7.4.2 was added to requirements.txt mid-session-48 but the docker image hadn’t been rebuilt; today’s rebuilds picked it up cleanly. The pierlog_qr route at /pierlog/qr.png now serves the static QR PNG that ships on stickers + the bilingual handout.

Pending follow-ups (not blocking)

  • iPhone end-to-end walkthrough on a real device (Tufte details, focus zoom, color states)
  • 4 legacy projects from backfill_pierlog_check.py (psi-vs-slab tagging ambiguity)
  • Office portal UI to consume pierlog_discrepancies (will be useful once data accumulates)
  • Vision parser hardening for the Phase A photo upload (unlikely.pics) — Jacob’s catalogued failure modes: 90° rotation, cropped headers, glare/shadow, two-column logs, missing pier-number labels
  • Phase B (PWA + Web Share Target) for unlikely.pics — deferred until Phase A has a full work week of usage