lakehouse/docs/counsel/COUNSEL_HANDOFF_EMAIL_2026-05-05.md
root fcd53168a0 phase 1.6: counsel handoff turnkey + seed_consent_version.sh + strict mode live
The remaining production blocker is counsel-calendar bottleneck
(review + sign-off). Engineering can't make counsel move faster,
but it CAN reduce the round-trip overhead:

(1) docs/counsel/COUNSEL_HANDOFF_EMAIL_2026-05-05.md — copy-paste
    email body J can send to outside counsel. Subject line + body
    + tarball attachment instructions + headline asks (A/B/C/D
    in priority order) + post-signature operator runbook. The
    pre-flight checklist + post-signature workflow turn what
    would have been "I'll figure out the email" into "click send."

(2) scripts/staffing/seed_consent_version.sh — turnkey
    post-signature deployment. Takes the path to a (presumably
    counsel-signed) consent template markdown, computes SHA-256,
    atomically merges into /etc/lakehouse/consent_versions.json
    (creating the file if absent, with per-seed audit metadata
    in _meta.seeded_at[]), restarts lakehouse.service, probes
    /biometric/health post-restart. Idempotent: re-running with
    the same hash is a no-op for the versions array but still
    appends a [reseed] entry to the audit metadata.
    Verified live against the eng-staged template — strict mode
    flipped clean, /biometric/health 200 post-restart.

(3) docs/PHASE_1_6_BIPA_GATES.md §6.5 — post-signature deployment
    runbook embedded in the gates doc. Three steps: counsel signs
    + commits → seed_consent_version.sh → strict-mode probe.
    Plus a "pre-counsel demo seed" subsection documenting how to
    exercise strict mode BEFORE counsel signs (using the
    eng-staged template hash) so the deployment workflow is
    proven before the legal critical path closes.

Strict mode flipped live — verified post-restart:
- /etc/lakehouse/consent_versions.json populated with the
  eng-staged template hash:
  8b09591a8dc15f59197affac48909ce943d575eee01705b42303acf3b32f5c56
- POST /biometric/subject/WORKER-1/consent with deadbeef hash:
  HTTP 400 + error="consent_version_unknown"
- POST with the known eng-staged hash: passes version check
  (then 404 subject_not_found on a ghost candidate, proving
  the gate is hash-aware not auth-broken)

The hash currently seeded is the ENG-STAGED template
(pre-counsel-signature). When counsel returns the signed text,
operator runs `seed_consent_version.sh` again with the
counsel-signed markdown — the new hash gets appended; the demo
hash stays in for backwards-compat with any consent records
collected during the pre-counsel demo period (none, today).

Production blocker is now genuinely just counsel calendar:
1. J transmits reports/counsel/counsel_packet_2026-05-05.tar.gz
   per the handoff email
2. Counsel reviews + signs (their billable time)
3. Counsel returns signed text → operator runs seed script
4. Strict mode flips to canonical hash → cutover complete

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 15:32:16 -05:00

7.4 KiB

Counsel Handoff — Copy-Paste Email Draft

Date assembled: 2026-05-05 Operator of record: J Prepared for: outbound transmission to outside counsel Tarball: reports/counsel/counsel_packet_2026-05-05.tar.gz Tarball SHA-256: see reports/counsel/counsel_packet_2026-05-05.manifest.txt

This is a copy-paste-ready email draft. Subject line + body below. Attach the tarball + manifest before sending. The email frames what counsel needs to do, by when, and what happens after they sign — so the calendar bottleneck has no excuse to sit longer than counsel's actual review time.


Subject line

Lakehouse staffing platform — Phase 1.6 BIPA pre-launch package, ready for legal review

Email body

Hi [Counsel name],

Engineering on the Lakehouse staffing platform has finished the
Phase 1.6 BIPA (740 ILCS 14) pre-launch substrate. Before we begin
collecting any real candidate biometric data (photographs), the
five engineering-staged documents in the attached package need
your review and, where indicated, your signature.

What's attached:

1. counsel_packet_2026-05-05.tar.gz — bundled review package
2. counsel_packet_2026-05-05.manifest.txt — per-file SHA-256
   integrity hashes (re-run `sha256sum -c` on receipt to verify
   nothing changed in transit)

Open the cover letter inside the tarball
(`docs/counsel/COUNSEL_REVIEW_PACKET_2026-05-05.md`) first — it
walks through the substrate, the specific items needing your
sign-off, and recommended review sequence.

Headline asks (in priority order):

  A. Biometric Retention Schedule v1
       — render into binding language, sign as countersigning
         party. Sets the public retention schedule required by
         BIPA §15(a).
  B. Biometric Consent Template v1
       — render Disclosures 1-3 into binding consent text, sign.
         This is the form a candidate signs before any photo is
         collected. Required by BIPA §15(b)(1)-(3).
  C. BIPA Destruction Runbook
       — review for legal sufficiency, attest. Procedural
         document; engineering wrote the steps, your role is
         confirming they satisfy BIPA §15(a) destruction.
  D. Pre-IdentityD Attestation (2026-05-03)
       — countersign as the legal party. Establishes the boundary
         that no biometric data was collected before the gates
         shipped. One-time defense artifact.

Item C also references a key-rotation runbook (E in the cover
letter) that's lower priority — opine when convenient.

What happens after you sign:

  - Once we have your countersignatures on A, B, and D, our
    operator deploys them to the public privacy policy + the
    intake UI. Engineering will hash the canonical signed text
    of (B) and add that hash to the gateway's consent_versions
    allowlist file (/etc/lakehouse/consent_versions.json) so the
    runtime starts refusing any consent record that wasn't
    signed under the canonical template. (The gateway is
    currently in permissive mode — accepting any non-empty
    hash. Strict mode flips on with your signature.)
  - The runtime gates are already enforcing the consent flow:
    photo upload refuses 403 unless consent.biometric.status =
    "given", and the only path to that state is the
    /biometric/subject/{id}/consent endpoint with a valid
    consent_version_hash. After your signature, that hash will
    point at canonical signed text — operator typo-resistant
    and counsel-defensible.

Calendar:

  - We'd like to begin real-photo intake within [N] weeks. If
    your review can land within 2-3 weeks of receipt, that
    keeps us on schedule. If your bandwidth requires longer,
    please flag — we have eng work to advance independently
    that doesn't depend on the signatures.

Open questions for you (sub-questions detailed per-doc inside
the cover letter):
  - Confirm 18-month operational retention ceiling vs BIPA's
    3-year statutory cap (we picked 18mo for safety margin)
  - Confirm 30-day SLA for destruction following withdrawal
    (some interpretations prefer 7 or 14)
  - Specify the public privacy policy URL where the retention
    schedule will be published
  - Specify the candidate-facing contact channel for withdrawal
    requests (we have an endpoint; you specify the comms surface)

Background context (not asks): the engineering substrate is
verified end-to-end. We've run a live demo of the full lifecycle
(consent → photo → withdraw) on a test subject; the audit chain
verifies cryptographically; the retention sweep is scheduled
daily. No real candidate photos have been collected. The
attached pre-identityd attestation has the cryptographic evidence
hashes from that pre-collection state.

Happy to schedule a call if any of this would be easier to walk
through verbally.

Thanks,
J
[contact info]

Operator pre-flight checklist (before sending)

Run through this once before clicking send:

  • Confirm tarball + manifest are the latest versions (bundle_counsel_packet.sh regenerates if needed; current hash is in the manifest sidecar)
  • Confirm counsel name is correct (and that the engagement letter or retainer is in place)
  • Confirm the [N] weeks calendar target — replace with a real number ("3 weeks" / "by end of June" / etc.)
  • Confirm the email goes to counsel's secure channel; if counsel uses a portal, upload there + send a notification email instead
  • Save a copy of the sent email + the tarball to operator records — this is itself part of the audit trail of "we asked counsel on [date]"

Post-signature operator runbook (after counsel responds)

When counsel returns the signed documents:

  1. Verify integrity. Run sha256sum -c manifest.txt on the returned tarball if counsel returns the bundle; otherwise compare returned signed PDFs against the markdown sources to confirm the binding text matches what counsel reviewed.

  2. Capture the canonical signed text. Counsel may sign a PDF rendering of the markdown — that's fine, but the BINDING TEXT we hash is the markdown source (counsel commits to git countersigning §7 of the consent template + §8 of the retention schedule).

  3. Compute + seed the consent_version_hash. Run:

    ./scripts/staffing/seed_consent_version.sh \
        docs/policies/consent/biometric_consent_template_v1.md
    

    This computes SHA-256 of the markdown, atomically merges it into /etc/lakehouse/consent_versions.json (creating the file if absent), and offers to restart the gateway.

  4. Verify strict mode is live. Probe with a known-bad hash:

    TOKEN=$(cat /etc/lakehouse/legal_audit.token)
    curl -sS -X POST http://localhost:3100/biometric/subject/WORKER-1/consent \
      -H "X-Lakehouse-Legal-Token: $TOKEN" \
      -H 'Content-Type: application/json' \
      -d '{"consent_version_hash":"deadbeef","consent_collection_method":"electronic_signature","operator_of_record":"smoke"}' | jq
    

    Expect HTTP 400 with error: "consent_version_unknown".

  5. Update STATE_OF_PLAY.md to record the signature event + the hash entry in the allowlist. Counsel-tier deployment is now live.

  6. Sign and anchor the §2 attestation. Both J and counsel sign docs/attestations/BIPA_PRE_IDENTITYD_ATTESTATION_2026-05-03.md and the SHA-256 of the signed markdown is committed to the git history as a tamper-evident anchor.

After step 5, the production cutover blocker is closed.