Date: 2026-05-15 (push mode, 60 min cadence, split-brain remediation iter)
This iter took the iter-124 cross-surface discovery (29 split-brain products) and fixed 24 of them in one pipeline-level sweep. The remaining 5 are hand-written content the generators don't touch.
Built /home/ubuntu/factory/director/brand_name_helper.py (~60 lines). Single source of truth for "what's the display name of this product?" Resolution order:
name: YAML field# Inkwell ยท Brand Brief)prod["name"] (legacy default)Provides two functions:
brand_brief_name(slug) - returns brand brief name or Nonedisplay_name(prod_or_slug, fallback_name=None) - returns the brand brief name OR canonical OR slugAny generator imports this and gets brand-rename support for free.
Used a batch patch script + manual edits to wire brand_brief_name(slug) into 8 surface generators. The 5 batch-patched (standard p.get("name", slug) pattern):
| Generator | Surface | Pattern | Replacements |
|---|---|---|---|
| faq-template-gen.py | faq | p.get | 1 |
| regen-unlock-pages.py | unlock | p.get | 2 |
| regen-adopt-pages.py | adopt | p.get | 1 |
| regen-feedback-page.py | feedback | p.get | 1 |
| regen-fallback-pricing.py | pricing | prod.get | 1 (manual) |
The 3 manually patched (used get_field(brand_text, "name") which only reads YAML field, not H1 fallback):
| Generator | Surface | Approach |
|---|---|---|
| regen-vs-pages.py | vs | brand_brief_name(slug) or get_field(...) or slug |
| regen-fallback-subpages.py | vs, how-it-works, skeptic-memos, sales-kit, about | same fallback chain |
| case-studies-gen.py | case-studies | same fallback chain |
Both regen-fallback-pricing.py and regen-fallback-subpages.py were idempotent (skip if index.html exists). Added FORCE_REGEN env flag to bypass for one-shot fixes.
ALSO added a custom-page preservation guard to regen-fallback-subpages.py (WD_PRESERVE_CUSTOM_SUBPAGE_v1): if the subpage directory contains any sibling asset files besides index.html, the generator skips it regardless of FORCE_REGEN. This protects custom hand-crafted page sets (e.g., the 4 full sales-kits with product-brief.html, roi-calculator.html, objection-handler.md etc.) from being overwritten by the gated fallback.
Ran all 8 patched generators with FORCE_REGEN=1 to propagate brand brief names to existing pages:
fallback-pricing (FORCE): wrote 246 new
faq-template-gen: wrote 237, skipped hand-written 9
unlock-pages: wrote 246
adopt-pages: wrote 246
feedback-page: wrote 246
vs-pages: wrote 17 of top 20 (custom)
fallback-subpages (FORCE): wrote 246 vs, 246 skeptic-memos, 246 how-it-works
case-studies-template: wrote 239, skipped hand-written 7
| Audit | Before | After |
|---|---|---|
| audit-cross-surface-name | 0/29 (FAIL) | 24/29 (WARN) |
| /quality-report/ card state | FAIL | WARN |
Examples of fixed products (all 11 surfaces now use brand name):
Remaining 5 split-brain (hand-written content the generators don't regenerate):
These are Wes-task fixes - either edit the hand-written content to use brand name OR add a hand-written-content brand-rename helper.
The fallback-subpages run initially overwrote 4 custom sales-kit index.htmls (audit-ai, contract-ai, dispatch-ai, lawfirm-ai) with the gated stub. The .html/.md asset files (product-brief, roi-calculator, etc.) are still on disk so direct URLs still work. The new WD_PRESERVE_CUSTOM_SUBPAGE_v1 guard prevents this from recurring on future runs.
Audit verifies: audit-sales-kit-content still 246/246 clean - the gated index.html is one of 3 accepted patterns.
4 substantive ships at 60-min cadence. This is the highest-impact iter since the early audit-suite buildout - one cross-cutting audit (iter 124) plus one pipeline-level fix (iter 125) reduced systemic drift from 29 products to 5. Pattern: cross-cutting audit finds the drift, shared-helper module + bulk generator patch fixes it.
The brand_brief_name helper + WD_PRESERVE_CUSTOM_SUBPAGE_v1 guard are reusable for future rename pipelines.
This is the second major systemic milestone after the audit-perimeter close (iter 123). The factory's rename pipeline is now consistent through the surface layer.