Completion Run — Ship Prep (Checkpoint C)

Branch: completion-run @ 885d92c · PR: #638 (draft) · Date: 2026-08-08 Verifier verdict: loop-0 FAIL-with-6-findings → loop-1 PASS (all six closed with adversarial evidence; full report verbatim: V_verifier_report.md in this directory)

What merging this PR does — measured, not assumed

Merging completion-run → main auto-deploys nothing:

The site changes go LIVE only at the owner-dispatched deploy (action 3 below).

Run ledger (what landed)

Commit Slice
9551ace/98b9d5f Phase A audit artifacts + checkpoint matrix (three parallel audits)
d910eed Owner-approved truth-discipline fix list (T/L/K/W rows, §03 dry-run line) + canon re-pin
a5349cf/40560c8 CMEK → design-target framing on all served surfaces + canon re-pin
bb1b27a Claims-backing test pack (110 tests pinning dossier mechanics; later 114)
1242794 Measurement Rails service — the build-to-claim core (192 tests, 96% coverage)
a74e8de content_qa rule E (claims ledger) + scope 12→25 + docs/BUILD_DEBT.md
adc5e6c (coordination lane) credential-free cell26 import hardening
885d92c Verifier loop-1: all six findings closed

Final gate outputs (fresh at 885d92c, verifier-run)

Claims outcome (zero unbacked present-tense claims remain)

Approval-gated diff awaiting the owner

Rollback notes

Owner's exact remaining actions

Start here: python3 scripts/operator_preflight.py — one read-only command that reports the live status of every tree-checkable item below (cost-config completeness per tenant, the DDL files the RUNBOOKs name, writeback-flag defaults, and the secret-name table vs. what the code actually reads). It makes no cloud calls and never claims a table, secret, revision, or scheduler job exists. DRIFT = docs and code disagree (fix in-tree first); ACTION = genuine outstanding operator work.

Items 1, 2, 3, 8 and 9 below are DONE — struck through with their evidence rather than deleted, so the record shows what closed and how.

  1. ~~Approve or amend dossier-stories.proposal.md~~ — DONE: owner approved; applied verbatim and live (commits 7774c52 → a023a43, deploy #59).
  2. ~~Mark PR #638 ready and merge~~ — DONE: owner-merged 2026-08-08T21:21Z. Follow-up hardening merged as PR #642.
  3. ~~Take the site copy live~~ — DONE: deploys #58, #59, #60 (each workflow_dispatch + typed APPROVED). Run #60 live-verified 23:06Z — the C38 "operating design, in development" label serves on /signal/audiences.
  4. Secret Manager (operator-credentialed — agents may not do this): create the five secret NAMES in docs/measurement-rails/RUNBOOK.md §3. The preflight verifies those names match the env vars the code actually reads, so a secret you create is one the service will use; it cannot verify the secrets exist in GCP.
  5. Configs (needs real data only you have): fill config/net_yield_costs.yaml with real landed costs — validate with python3 services/net-yield/cost_config.py, which names every still-missing cost per tenant in the same vocabulary the compute path writes to missing_costs (exit 0 complete · 1 gaps · 2 schema invalid). Replace config/measurement_rails/lag_profiles.yaml operating defaults with per-source empirical fits as data lands. Nothing is ever defaulted or inferred.
  6. Run the RUNBOOKs (operator-credentialed): apply the DDL, deploy the services, create the scheduler jobs. Both RUNBOOKs now open with the preflight step. Nothing runs until you do it.
  7. Flag order: per-rail validate-only → dry-run → live per engagement; MEASUREMENT_WRITEBACK strictly last (it backs an existing page claim); NET_YIELD_WRITEBACK stays off until a verified pilot per the claim ledger; Preview labels flip only per the claim ledger. Enforced in code, not just prose: both defaults are literal-False test-pinned, an ambient-env sentinel turns the rails suite red if either flag is flipped in the environment, and the preflight re-checks the documented deploy command ships every flag false.
  8. ~~Workflow owner: validate-manifests.yml permissions~~ — DONE: job-level permissions: {issues: write, pull-requests: write} plus continue-on-error on the comment step are on main; a comment failure can no longer red the check suite.
  9. ~~Coordinator lane: JourneyEvent schema-hash pin~~ — DONE: main pins the measured 8d7aace5d6f5…. That was the last standing red in Lint, Test, and Validate.

Residual backlog (not violations)


Reconciliation addendum (2026-08-08, second lane)

Two sessions raced this mission after the owner re-issued the prompt; both ran independent Phase V verifiers and fixed overlapping finding sets. Union-merged in 37dbb43 (this lane's commits 8e8e4d5/ffac680 + the first lane's 885d92c/c11eb2e), adopting the first-pushed wording on shared spots and keeping each lane's unique fixes:

Union gates at 37dbb43: content_qa 25 clean + self-test PASS · canon 20/20 · site suite 428 passed / 2 pre-existing base failures · claims pack exit 0 (130 tests) · rails 194 (+ env-flip run red by the sentinel) · net-yield 59 · skills parity OK · memory strict PASS.

Durable process lesson (recorded in governed memory): a byte-length-preserving mutation probe reverted within the same mtime second leaves a stale __pycache__ .pyc that git cannot see — Python serves the mutated constants while the tree reads clean. Purge bytecode caches before scoring any suite run and after every mutation probe.

← All docsView source on GitHub →