← back to Designer Wallcoverings
merge-staging: fold DTD-A fallback titles into merged set (title 37->100%); gate-readiness: word-boundary fix for BAD_TITLE_TOKENS (LW1404 '404' false-match). Gates untouched: cost 0, activation_ready 0.
151d386df1b87e9f7c2db3c56d065abc3c583791 · 2026-07-01 15:05:54 -0700 · Steve
Files touched
M onboarding/sangetsu-lilycolor/scripts/gate-readiness.pyM onboarding/sangetsu-lilycolor/scripts/merge-staging.py
Diff
commit 151d386df1b87e9f7c2db3c56d065abc3c583791
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jul 1 15:05:54 2026 -0700
merge-staging: fold DTD-A fallback titles into merged set (title 37->100%); gate-readiness: word-boundary fix for BAD_TITLE_TOKENS (LW1404 '404' false-match). Gates untouched: cost 0, activation_ready 0.
---
.../sangetsu-lilycolor/scripts/gate-readiness.py | 10 +++++--
.../sangetsu-lilycolor/scripts/merge-staging.py | 35 ++++++++++++++++++++--
2 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/onboarding/sangetsu-lilycolor/scripts/gate-readiness.py b/onboarding/sangetsu-lilycolor/scripts/gate-readiness.py
index 1e1d7c41..61b2df86 100644
--- a/onboarding/sangetsu-lilycolor/scripts/gate-readiness.py
+++ b/onboarding/sangetsu-lilycolor/scripts/gate-readiness.py
@@ -58,10 +58,14 @@ def title_guard_ok(d):
if BANNED in t.lower(): # "wallpaper" is banned ANYWHERE in the title
return False
# Error tokens (unknown/404/not found/…) are only meaningful in the PATTERN-NAME
- # segment (before the first pipe). Checking the whole title false-matched "404"
- # inside SKU ranges like LL6404 / LV2404.
+ # segment (before the first pipe), AND only as WHOLE words — a substring check
+ # false-matched "404" inside SKU codes like LL6404 / LV2404 / LW1404 (the
+ # MFR-SKU-fallback titles are legitimately just the SKU code).
pattern_seg = re.split(r"[||]", t)[0].strip().lower()
- return not any(tok in pattern_seg for tok in BAD_TITLE_TOKENS)
+ for tok in BAD_TITLE_TOKENS:
+ if re.search(r"(?<![0-9a-z])" + re.escape(tok) + r"(?![0-9a-z])", pattern_seg):
+ return False
+ return True
def has_description(d):
diff --git a/onboarding/sangetsu-lilycolor/scripts/merge-staging.py b/onboarding/sangetsu-lilycolor/scripts/merge-staging.py
index 484b9753..b912a264 100644
--- a/onboarding/sangetsu-lilycolor/scripts/merge-staging.py
+++ b/onboarding/sangetsu-lilycolor/scripts/merge-staging.py
@@ -6,6 +6,10 @@ OFFLINE / non-gated prep. Left-joins onto the 2,543 unified-staging records
(the publishable universe, keyed by mfr_sku):
- design enrichment (enrichment-full-063026A.jsonl, key: sku)
- EN titles (lilycolor-titles-en-063026A.jsonl, key: sku)
+ - FALLBACK titles (lilycolor-titles-fallback-063026A.jsonl, key: sku)
+ DTD-A synthesized titles for the 1,580 title-less SKUs (title_ja null).
+ Only applied when the record still has NO title after the JA/EN join —
+ so a real scraped/translated title always wins over the fallback.
Preserves every gating flag exactly as-is (cost_confirmed, activation_ready,
status) — this script NEVER flips a gate. It only co-locates the staged data
@@ -31,6 +35,7 @@ ENRICH = os.path.join(STAGING, "enrichment-full-063026A.final.jsonl")
if not os.path.exists(ENRICH):
ENRICH = os.path.join(STAGING, "enrichment-full-063026A.jsonl")
TITLES = os.path.join(STAGING, "lilycolor-titles-en-063026A.jsonl")
+FALLBACK = os.path.join(STAGING, "lilycolor-titles-fallback-063026A.jsonl")
OUT = os.path.join(STAGING, "lilycolor-merged-063026A.jsonl")
ORPHANS = os.path.join(STAGING, "lilycolor-merge-orphans-063026A.json")
@@ -68,13 +73,16 @@ def load_by_key(path, key):
def main():
enrich = load_by_key(ENRICH, "sku")
titles = load_by_key(TITLES, "sku")
+ fallback = load_by_key(FALLBACK, "sku")
n_out = 0
n_enriched = 0
n_titled = 0
n_both = 0
+ n_fallback = 0
used_enrich = set()
used_titles = set()
+ used_fallback = set()
with open(UNIFIED) as fin, open(OUT, "w") as fout:
for line in fin:
@@ -109,6 +117,28 @@ def main():
else:
rec["_titled_en"] = False
+ # FALLBACK titles (DTD-A) — only when the record STILL has no title
+ # after the JA/EN join. A real title always wins over a synthesized
+ # one; gates are untouched (this only fills title_en so publish has a
+ # non-empty, compliant, guard-passing title for every SKU).
+ has_real_title = bool((rec.get("title_ja") or rec.get("title_en") or "").strip())
+ if not has_real_title:
+ fb = fallback.get(sku)
+ if fb and fb.get("title_en"):
+ used_fallback.add(sku)
+ rec["title_en"] = fb["title_en"]
+ rec["pattern_en"] = fb.get("pattern_en")
+ rec["_titled_fallback"] = True
+ rec["needs_pattern_name"] = True # synthesized — reviewable
+ if fb.get("settlement_required"):
+ # LIS Morris & Co birds/foliage — GATE before publish.
+ rec["settlement_required"] = True
+ n_fallback += 1
+ else:
+ rec["_titled_fallback"] = False
+ else:
+ rec["_titled_fallback"] = False
+
if e and t:
n_both += 1
@@ -129,8 +159,9 @@ def main():
print(f"merged records written : {n_out} -> {os.path.relpath(OUT, HERE)}")
print(f" with design enrichment: {n_enriched} ({100*n_enriched//n_out}%)")
- print(f" with EN title : {n_titled} ({100*n_titled//n_out}%)")
- print(f" with BOTH : {n_both}")
+ print(f" with EN title (join) : {n_titled} ({100*n_titled//n_out}%)")
+ print(f" with FALLBACK title : {n_fallback} (DTD-A, title-less SKUs; needs_pattern_name)")
+ print(f" with BOTH enrich+title: {n_both}")
print(f"orphans (enrich/title) : {len(enrich_orphans)}/{len(title_orphans)}"
f" -> {os.path.relpath(ORPHANS, HERE)}")
# sanity: gates must all still be closed at this staging phase
← f1960768 title-fallback.py: synthesize compliant titles for 1580 titl
·
back to Designer Wallcoverings
·
auto-save: 2026-07-01T15:07:02 (7 files) — DW-Programming/Im 8da7b499 →