Shopify Lane Closeout + Expansion — Consolidation Build Report (2026-08-27)
Status: LANDED ON main. Correction 2026-09-02 (FINISH_IT_STATUS_2026-09-02
§P-2.3): the original status line below read "local-only, NOT PUSHED", which was
stale — the tree wins over the doc (.claude/rules/01). Measured landing commit
of the W1–W6 code: git log --diff-filter=A -1 origin/main -- services/net-yield/returns_adjustment.py
→ 8e63d0dac (2026-09-02), whose auto-merge subject names the branch
claude/mem-superseded-key-r2 — a branch name that does not describe its contents,
so ancestry-by-name misleads and only content settles it. Verify per flag on
main: RETURNS_ADJUSTED_NCM, INVENTORY_SPEND_GATE, RETENTION_COHORTS,
CREATIVE_FATIGUE, KLAVIYO_FEED all default-OFF by source literal.
Original status line (historical, now corrected): Consolidated on
claude/shopify-closeout-expansion-v1.0, local-only, NOT PUSHED. All gates below
are green except one pre-existing, unrelated red inherited from origin/main.
Consolidated tip: 51cbb7a6 (branch claude/shopify-closeout-expansion-v1.0,
worktree wt-w1, fast-forwarded onto the consolidation branch tip after all
merges below).
1. Per-workstream detail
W1 — Returns-Adjusted Net Yield
- Flag:
RETURNS_ADJUSTED_NCM(source literalos.environ.get("RETURNS_ADJUSTED_NCM", "false")— default OFF,services/net-yield/flags.py:23-27). - Files: 17 changed (net-yield
bq.py,main.py,order_economics.pyextended; newreturns_adjustment.py,flags.pyaddition,config/net_yield_costs.yaml,services/net-yield/bigquery/schemas/net_yield_refund_ledger.sql— additiveCREATE TABLE IF NOT EXISTS). - Tests added:
test_returns_adjustment.py(23),test_returns_adjusted_governance.py(11),test_returns_adjusted_f2_bridge.py(4),test_flags_returns_adjusted.py(6),test_bq.py(9), plus extensions totest_order_economics.py/test_api.py. Fullservices/net-yieldsuite: 173 passed. - Commits:
f8bf991e(claim) →46b8f07f(feat) →b3a1cf3e(docs: build report,docs/reports/SHOPIFY_CLOSEOUT_EXPANSION_W1_RETURNS_ADJUSTED_NET_YIELD_2026-08-27.md). - sha256 (
returns_adjustment.py):d2d832fdfadf68b86e9fc250245cd7e66af830e8fb81291897d458895221a9e8
W2 — Inventory Spend Gating
- Flag:
INVENTORY_SPEND_GATE(source literalINVENTORY_SPEND_GATE_DEFAULT = False,services/service-action-runner/execution_adapters/inventory_gate.py:47). Observe-only ("would_gate") first; DEL §3 mechanical demotion is a hard constraint, never advisory. - Files: new
contracts/mizoki_contracts/inventory_spend_gate.py,inventory_gate_store.py,services/service-action-runner/execution_adapters/inventory_gate.py,config/inventory_spend_gate.yaml(fail-closed, no invented SKU rosters or velocity — reads live units frommizoki_unified_data.market_signals),bigquery/schemas/inventory_gate_shadow.sql(additive). - Tests added:
test_inventory_spend_gate.py(19),test_inventory_gate_store.py(7),test_inventory_gate_wiring.py(12), plus an extension totest_new_store_erasure_posture.pyfor the new store's erasure posture. - Commits:
a6be8543(claim) →0773fa9f(feat) →b24c01d9(closeout record). - sha256 (
inventory_spend_gate.py):daba08143a7626098edc9285fc2df7870650ddf805668afff8c3e11e25017b04
W3+W4 — Retention Cohorts + Creative Fatigue
- Flags:
RETENTION_COHORTS(RETENTION_COHORTS_DEFAULT = False,src/shared/growth_control/f2_ltv/retention_cohorts_advisory.py:77) andCREATIVE_FATIGUE(CREATIVE_FATIGUE_DEFAULT = False,src/shared/creative_aesthetic/fatigue_detection.py:92). Both advisory-only. - Files: new
retention_cohorts_advisory.py(repeat-rate + return-adjusted LTV off existing F2order_economicscurves),fatigue_detection.py(frequency × CTR-decay off Meta/Google reporting ingest, joinscreative_vectors),bigquery/schemas/retention_cohorts_advisory_ddl.sql+creative_fatigue_ddl.sql(both additiveCREATE TABLE IF NOT EXISTS+CREATE OR REPLACE VIEW). Cross-referenced pre-existing, unrelatedboss/creative_fatigue_integration.py— not touched. - Tests added:
test_retention_cohorts_advisory.py(21),test_creative_fatigue.py(26). - Commits:
430ea860(feat) →57d22d23(completion record). This branch forked from a newer main tip (bbc9b8cc) than W1/W2/W5W6 (038158d1) — its own merge into the consolidation branch surfaced a real conflict in.claude/memory/index.json/manifest.json(resolved by regenerating viascripts/claude_memory.py reindex, see §2). - sha256 (
fatigue_detection.py):e1c30fc3b76e98fb4a5aa005959ecfd535cc60c1bc1fb9728f69442e663aba61 - sha256 (
retention_cohorts_advisory.py):f1ed93821b53318f64bd1b425ee2d92bf0831bab49ce814ebdeb53f400cbfaaf
W5+W6 — Klaviyo Value Feed + Onboarding Pack
- Flag:
KLAVIYO_FEED(services/measurement-rails/flags.py:52, default OFF like every other rail). E[NCM]-shaped events only (margin, never raw revenue) — mirrors the Meta CAPI / Google EC rail pattern. - Files: new
klaviyo_feed.py,cogs_worksheet.py(COGS worksheet generator +humanize_rejects),docs/product/SHOPIFY_ONBOARDING.md; extendsncm_feed_wiring.py,reconciliation.py(identity-coverage meter),shopify_install.py(OAuth merchant-error copy),service-marketing-connectors/main.py. - Tests added:
test_rails_klaviyo.py(16),test_cogs_worksheet.py(13), extensions totest_ncm_feed_wiring.py,test_reconciliation.py,test_shopify_install.py. - Commit:
f3112c19(single squashed commit for the whole workstream — local, not pushed at time of commit). - sha256 (
klaviyo_feed.py):27cf2d6aa87ed934ed24e869038084beb5e9fb0ca7dcea0d53d541f82d190e73 - sha256 (
cogs_worksheet.py):da8fc43fd22255b1137c7e13390458504afc393f5759405baa8c6ba89cf1e386 - sha256 (
SHOPIFY_ONBOARDING.md):6bcc95784d1d4285a6e09dfb4eff7caea75600751a03da3684fa2a8484bc7252
Step 0 fix (independent of W1–W6, already on origin/main at 97e591d4)
While consolidating, origin/main was found to be 5 commits ahead of the
branch point used for W1/W2/W5W6, including 97e591d4
("fix(shopify-closeout): pin PIXEL_EVENTS_ENABLED source literal; correct
stale ghost-bid claim") — an independent verification session's fix for
exactly the same gap W5+W6 had also patched (a missing source-literal test on
PIXEL_EVENTS_ENABLED in services/intent-shopify-extender/test_pixel_events.py).
The duplicate was real: after merging origin/main into the consolidation
branch, both fixes landed in the same file (git's merge algorithm combined
them without a textual conflict, since they touched different line ranges),
producing two PixelEventsFlagLiteralTests classes with the same name — the
second silently shadowed the first, quietly dropping test coverage.
Resolved: kept origin/main's AST-based version (already reviewed, has a
full verification report docs/reports/SHOPIFY_CLOSEOUT_VERIFY_2026-08-27.md
backing it) and removed W5+W6's regex-based duplicate (including the
now-unused import re). Also merged in the origin commit's other fix
(docs/product/FEATURE_COVERAGE_MATRIX_v1.md rows 2.7/G-03, ghost bids
PROPOSED→PARTIAL (DARK)) — no conflict with W5+W6's own row 4.8 addition to
the same file (different rows).
2. Consolidation mechanics and defects found/fixed en route
Consolidation worked branch-by-branch (git merge --no-ff) into a fresh
worktree, in order W1 (base) → W2 → W3+W4 → origin/main (5 commits) → W5+W6,
landing at tip 51cbb7a6. No code files overlapped between W1–W5+W6 — every
real conflict was in the memory system (.claude/memory/index.json,
manifest.json, CLAUDE.md), which each workstream's own local memory
rollover had touched independently.
.claude/memory/index.json/manifest.jsonconflicts (2×, on the W3+W4 merge and the origin/main merge): resolved by taking either side and runningpython3 scripts/claude_memory.py reindex— these are pure generated artifacts, never hand-merged.- CLAUDE.md ledger splice (real defect, caught by
check --strict): themerge=uniondriver (.claude/rules/02-multi-session-coordination.md's documented splice hazard) dropped the body of the "W2 inventory-spend-gating - built, observe-only, flag OFF" heading and misattached it under the
unrelated "v5.3 closed by owner merges; Actions outage found" heading.
Recovered both bodies byte-verbatim from their source commits (
b24c01d9for W2's,97e591d4for v5.3's) and re-attached them to their correct headings.check --strictclean after the repair. - PIXEL_EVENTS_ENABLED duplicate — see §1 above.
- Hazard found, not touched:
.git/hooks/post-mergerunsrsync -a --delete "$(git rev-parse --show-toplevel)/" "$DRIVE"/on every merge. Run from a scratch worktree,--show-toplevelresolves to the worktree, not the main checkout — a merge there wouldrsync --deletethe Google Drive clone against an incomplete/wrong tree. The first merge attempt hung for 2 minutes against an unresponsive CloudStorage mount and was killed before any file writes were observed (Drive-clone top-level mtime unchanged at Aug 25, and the mount was independently confirmed unresponsive to a plainfind). All subsequent git operations for this work used-c core.hooksPath=<empty dir>to disable hooks entirely. This local hook is not part of the governedsync-drivemechanism in CLAUDE.md §6 and is a standing hazard for any future worktree-based git operation on this machine — recommend the owner either scope it to the main checkout only or replace it with the governed checksum-based sync.
3. Consolidated gate results (fresh venv, wt-w1 @ 51cbb7a6)
Fresh venv built from the union of every touched service's requirements.txt
plus pip install -e contracts (rule 01: never trust a reused venv).
| Suite | Result | R3/register baseline | Note |
|---|---|---|---|
services/measurement-rails |
443 passed, 2 warnings, 7 subtests | 396 | |
tests/connectors |
340 passed | — (part of gateway+connectors 220) | |
services/service-marketing-connectors |
162 passed | — | combined w/ above = 502 vs. 220 baseline |
services/intent-shopify-extender |
41 passed | 20 | incl. the reconciled PixelEventsFlagLiteralTests |
services/net-yield |
173 passed | — (new W1 suite) | |
tests/governance |
all green, exit 0, 100% (no F/E marks) | — | new W2/W3/W4 tests included |
tests/remediation |
305 passed, 1 failed | — | see below — pre-existing, unrelated |
The one failure — tests/remediation/test_contracts_hardening.py::test_domain_covers_all_six_platform_domains
— is PRE-EXISTING on origin/main and unrelated to this work. Reproduced
directly against origin/main's own contracts/ and test file (checked out
in isolation, same failure): Domain enum carries an extra 'calibration'
member the test's hardcoded six-domain set doesn't expect. Not touched or
introduced by any W1–W6 workstream. Per .claude/rules/01-verification-discipline.md
("reproduce a claimed pre-existing failure against the base branch before
accepting it as pre-existing") — reproduced, confirmed, out of scope here.
Canon / skill / governance checks — all green
python3 scripts/mizoki_canon.py --check → exit 0
python3 scripts/skill_sync.py --check → parity OK — 14 skills, derived copies match, registry current
python3 scripts/skills_sync.py --check → [skills-sync] OK — all skill copies byte-identical, versions in parity
python3 scripts/ontology_skills_sync.py --check → Ontology-KG Virtuoso parity: OK (8 profiles)
python3 scripts/claude_memory.py check --strict → [WARN] root-warning-limit only; validation PASS
Rule 03 pre-merge hygiene greps (scoped to files touched by this consolidation)
- V1 (SRDAL): zero real hits — the one match is a legal reference to "SRDAL / retired model strings" as a list of grep categories inside a build report, not a claim.
- V2 (retired model strings): zero hits.
- Hardcoded model-string literals in code: zero — all matches were memory-index metadata (
claude-rollover-*record ids, a service namegemini-kg-pipeline, andclaude-opus-5inside an archived memory record's search terms), none in application code. - Banned-content categories (Airbnb KL / Quokka / audio-keystroke-gaze / mind-reading / 32-cell / Neo4j-for-Cell-35): none of W1–W6's new files touch
docs/; the onlydocs/change from this consolidation is the already-sweptSHOPIFY_CLOSEOUT_VERIFY_2026-08-27.md(clean per its own §8) andFEATURE_COVERAGE_MATRIX_v1.md/SHOPIFY_ONBOARDING.md(both spot-checked, no banned terms).
Flag defaults — all five new flags confirmed OFF at the source literal
| Flag | File | Default |
|---|---|---|
RETURNS_ADJUSTED_NCM |
services/net-yield/flags.py:27 |
os.environ.get(..., "false") |
INVENTORY_SPEND_GATE |
services/service-action-runner/execution_adapters/inventory_gate.py:47 |
INVENTORY_SPEND_GATE_DEFAULT = False |
RETENTION_COHORTS |
src/shared/growth_control/f2_ltv/retention_cohorts_advisory.py:77 |
RETENTION_COHORTS_DEFAULT = False |
CREATIVE_FATIGUE |
src/shared/creative_aesthetic/fatigue_detection.py:92 |
CREATIVE_FATIGUE_DEFAULT = False |
KLAVIYO_FEED |
services/measurement-rails/flags.py:52 |
off, same pattern as every other rail |
Every flag also carries its own source-literal (AST or regex) test, per rule 01 ("every safety default carries a test that fails if the default is flipped").
Protected paths and site-visible files
git diff --name-only origin/main HEAD | grep -E '^\.github/|^deployment/terraform/|^deployment/cloudbuild|^CODEOWNERS' → empty
git diff --name-only origin/main HEAD | grep -iE 'website|homepage|marketing/index|signal\.html|media/index' → empty
Zero protected-path or site-visible files in the 54-file / 5,831-insertion /
728-deletion diff against origin/main. No conflict markers remain anywhere
in the tree (verified with a repo-wide grep after every merge).
4. Rollback plan
- Level 1 — flags (seconds, no redeploy). Every new capability
(
RETURNS_ADJUSTED_NCM,INVENTORY_SPEND_GATE,RETENTION_COHORTS,CREATIVE_FATIGUE,KLAVIYO_FEED) ships OFF and is independently togglable. If any one misbehaves post-deploy, its own env var reverts it without touching the others or requiring code changes. - Level 2 — Cloud Run revision rollback. Every merge to
mainfrom this branch prefix triggersdeploy-*.ymlfor each path-matched service (net-yield, measurement-rails, service-action-runner, service-marketing-connectors, intent-shopify-extender). Standard rollback:gcloud run services update-traffic <svc> --to-revisions=<prior-revision>=100per.claude/rules/04-deployment-and-perimeter.md's registry-truth convention — identify the prior-Ready revision fromproduction/service-registry.yaml/gcloud run revisions listbefore rolling back. - Level 3 — schema. All four new BigQuery DDL files
(
net_yield_refund_ledger.sql,inventory_gate_shadow.sql,creative_fatigue_ddl.sql,retention_cohorts_advisory_ddl.sql) are additive-only —CREATE TABLE IF NOT EXISTS/CREATE OR REPLACE VIEW, zeroALTER/DROPstatements (verified by grep, §3). Rolling back the code never requires a schema rollback; the tables/views simply go unused. - No migration, no backfill, no destructive step anywhere in this consolidation.
5. Operator remainder (nothing in code substitutes for these — from the
Step 0 verification, re-confirmed unchanged by this consolidation)
- Shopify app creation (client_id/secret) — no real credential in code or
terraform;
TokenRefreshError("oauth_client_unconfigured")when absent. (Corrected 2026-09-30: this is the code posture only — the app exists (miz-oki-commerce-link-5, S-4 CLOSED), OAuth is armed since 08-21 and both secrets are populated and mounted since 08-25; the remainder is the first install.) SHOPIFY_WEBHOOK_SECRET/ provider credentials — fail-closed (401 invalid Shopify webhook HMAC) when unset. (Corrected 2026-09-30: set and mounted since 08-25; the verifier's key choice is defect D1, PR #1275.)- Pixel extension artifact / extender URL —
SHOPIFY_PIXEL_COLLECT_URLunset by default; activation deferred loudly ("status": "deferred", "reason": "pixel_collect_url_unset"), plus an equivalent deferral forSHOPIFY_PIXEL_INGEST_SECRET. - Reconciliation runner credentials — inert without merchant credentials
(register item 6) and a
--events-table/RECONCILIATION_EVENTS_TABLE. KLAVIYO_PRIVATE_API_KEY(new, W5) —klaviyo_feed.health()reportsnot_configureduntil set; the value push half stays dark regardless of theKLAVIYO_FEEDflag until this lands.net_yield_costsreal values —config/net_yield_costs.yaml(W1) is fail-closed by design: every null cost marks dependent orderseconomics_complete=falserather than inventing a default.INVENTORY_SPEND_GATE_CONFIG_PATHroster/velocity declarations — W2's config ships empty by design; a tenant with no usable block getsinventory_spend_gate: not_configured, not an invented demotion.- 10 design partners — P1 exit criterion
(
docs/roadmap/P1_BUILD_PLAN.md,docs/product/SIGNAL_SHOPIFY_MASTER_v4.md) is owner-recruiting, unaffected by this consolidation; none of W1–W6 changes that count or its mechanism.
None of the above is substituted with code by this consolidation — every fail-closed / defer-loudly path is preserved and, where new, tested.
6. Open owner decisions — unchanged by this consolidation
Per the Step 0 verification (docs/reports/SHOPIFY_CLOSEOUT_VERIFY_2026-08-27.md
Item 6), decisions 3, 9, 12, 13, 14, 15, 17 remain genuinely open with zero
resolution in any record as of 2026-08-27. (Superseded 2026-09-15: all but 14 are
CLOSED by owner ruling — docs/OPEN_ITEMS.md §A; noted 2026-09-30.) Decision 9 (citation sign-off) is
unblocked (5/5 PASS) but not formally closed. None of W1–W6 touches or
requires any of these. The Article VI cell-count item is resolved (39
registered cells) and not a live open item.
7. What is NOT done by this report
- ~~Not pushed.~~ (Landed: see the header correction —
51cbb7a6and the W1 commit46b8f07f3are ancestors ofmainvia merge8e63d0dac, 2026-09-02; measured 2026-09-30.) Original line:claude/shopify-closeout-expansion-v1.0is local-only at tip51cbb7a6, ready for push only on ownerAPPROVED: MERGE. - Not live-verified. Everything above is
implemented+ gate-green on a fresh venv, neverlive-verifiedordeployed— those states require the push, the merge-triggered deploys, and a post-deploy probe of each serving revision, none of which have happened yet. - Pre-existing red not fixed:
test_domain_covers_all_six_platform_domainsstays failing onorigin/mainafter this consolidation (out of scope; flagged for a separate session/owner call, not silently absorbed into this branch's scope).