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 marketing site ships ONLY via human
workflow_dispatchofdeploy-homepage.ymlwith the typedAPPROVEDtoken, gated by the canon check and content_qa (GOVERNANCE.md 2.1). Merge ≠ site deploy. services/measurement-rails/**is Deploy-Router-inert — nodeploy-*.ymlmatches any of its paths (router-match proof pasted indocs/measurement-rails/ADR-MR-001.md§1; independently re-verified in Phase V).- No boss modules, no
src/shared/**, no workflows, noservices/net-yield/**runtime code were touched. - The branch name is deliberately outside the Auto-Merge bot's patterns (
claude|gemini|codex|copilot|cursor/**) so the merge is an owner click, not a bot action.
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)
- content_qa:
SELF-TEST PASS(all seed classes incl. rule E a–d + the<N msclass) ·CONTENT QA OK — 25 scoped files clean - Canon:
CANON OK — 20 core surfaces match v1.5-night-dossier - Suites: site 429 ran / 2 failed (both pre-existing homepage failures, reproduced at merge-base) · measurement-rails 192 · net-yield 59 · claims_backing 114 · marketing-site 64 · content_qa 19 · virtuoso 29P/1F/4S (the 1F is the JourneyEvent schema-pin, pre-existing on base — coordinator lane owns reconciliation)
- Flag-flip proofs:
MEASUREMENT_WRITEBACKdefault flip → 4 tests fail → revert green;NET_YIELD_WRITEBACKflip → 3 fail → revert green. No live HTTP possible: zero network libs in rails/writeback modules; sends require flag ON +dry_run=False+ injected transport; socket tripwire proven. scripts/skills_sync.py --checkOK ·claude_memory.py check --strictvalid · nothing from this branch onmainexcept the two documented coordination memory records (each touches onlyCLAUDE.md+.claude/memory/index.json).
Claims outcome (zero unbacked present-tense claims remain)
- BACKED-BY-CODE: 36 ids (M1–M9, A10–A14, C19b–C47 families) — every ledger evidence path exists; every cited test exercises the real mechanism.
- LABELED-DEBT / RELABELED: 4 (C42, C43, C45 copy fixed; C46 CMEK design-target + CMEK-1).
docs/BUILD_DEBT.md: 7 rows (GB-1, RF-1, RL-1, AU-1, CL-26, LEG-1, CMEK-1), enforced by content_qa rule E both directions.
Approval-gated diff awaiting the owner
docs/completion-run/dossier-stories.proposal.md— five per-dossier story excerpts (Doorman→audiences, CFO/brand-search→budget, Coupon→budget, Prove-It-Or-Lose-It→measurement, Bundle→measurement) with exact insertion anchors. Not applied.- (The executive-briefing PROVE→PROFIT→ANTICIPATE restructure was already applied under the 2026-08-07 owner approval — no second proposal needed.)
Rollback notes
- Site copy:
git revertofd910eed/a5349cf/40560c8/885d92cwith a same-commitcheck_design_canon.py --updatere-pin. Nothing is live until a dispatch, so pre-dispatch rollback is repo-only. - Rails: revert
1242794— no revision, scheduler, table, or secret exists yet (RUNBOOK hands the operator every command), so revert is complete rollback. - Gate: revert
a74e8derestores the 12-file scope and removes rule E; ledger/BUILD_DEBT are docs. - Flags: both writeback flags default false and are test-pinned — there is no live behavior to roll back anywhere in this PR.
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.
- ~~Approve or amend
dossier-stories.proposal.md~~ — DONE: owner approved; applied verbatim and live (commits7774c52→a023a43, deploy #59). - ~~Mark PR #638 ready and merge~~ — DONE: owner-merged 2026-08-08T21:21Z. Follow-up hardening merged as PR #642.
- ~~Take the site copy live~~ — DONE: deploys #58, #59, #60 (each
workflow_dispatch+ typedAPPROVED). Run #60 live-verified 23:06Z — the C38 "operating design, in development" label serves on/signal/audiences. - 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. - Configs (needs real data only you have): fill
config/net_yield_costs.yamlwith real landed costs — validate withpython3 services/net-yield/cost_config.py, which names every still-missing cost per tenant in the same vocabulary the compute path writes tomissing_costs(exit 0 complete · 1 gaps · 2 schema invalid). Replaceconfig/measurement_rails/lag_profiles.yamloperating defaults with per-source empirical fits as data lands. Nothing is ever defaulted or inferred. - 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.
- Flag order: per-rail validate-only → dry-run → live per engagement;
MEASUREMENT_WRITEBACKstrictly last (it backs an existing page claim);NET_YIELD_WRITEBACKstays 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-Falsetest-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. - ~~Workflow owner:
validate-manifests.ymlpermissions~~ — DONE: job-levelpermissions: {issues: write, pull-requests: write}pluscontinue-on-erroron the comment step are onmain; a comment failure can no longer red the check suite. - ~~Coordinator lane: JourneyEvent schema-hash pin~~ — DONE:
mainpins the measured8d7aace5d6f5…. That was the last standing red inLint, Test, and Validate.
Residual backlog (not violations)
- R1: content_qa's tag-stripper swallows a raw unescaped
<100msin HTML (entity form is caught; raw form caught in .js/.md). - R2:
marketing/*(except governance) remains outside content_qa scope — owner call on scoping the parallel site. - BUILD_DEBT rows GB-1 … CMEK-1 as filed.
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:
- Kept from lane A (first push): signal.html C20 design-framed sentence; signal-thresholds
"playbook pattern store" wording; C24–C26 pins in
test_c22_c23_relu_threshold_agents.py; marketing proof-strip<100msdesign-target label + content_qa<N-msregex arm + s7 seed;SHIP_PREP.md+V_verifier_report.md. - Added by lane B (this lane): ambient-env sentinel —
MEASUREMENT_WRITEBACK=true(or any rail flag) now fails the rails suite by a named test, closing the env-flip criterion that the code-default flip proof alone did not cover; C34 ledger evidence re-cited off the driftedlift-engine/tests/test_causal_reasoning.py(pre-existing 23F on main) onto new behavioral pins intests/claims_backing/test_c34_bandit_pins.py; C39 ledger row + shopifypage_coverageextended to[C39, C40, C41]; signal-audiences C38 tail relabeled "— operating design, in development.";StatTileBasisTestCasepinning the index stat tiles; extra C24–C26 call-site-fallback pins; credential-free cell26 import (adc5e6c). - Evidence unions: C24–C26 cite both pin files; C41 adds the governed-memory archive
citation (
.claude/memory/archive/2026-08-07-CLAUDE-7.0.0-dea09569fc27.md) per the Phase A matrix resolution; C45 adds the stat-tile test. - Second verifier:
PHASE_V_VERIFIER_REPORT_2.md(verbatim report + loop-1 addendum, overall PASS after fixes; zero unexplained FAILs; loop-2 union check appended there).
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.