[object Object]

← back to Dw Yolo Loop

cycle 87: nav-link reachability (DTD unanimous A) — storefront runs Boost PFS; /collections/all Shop-All = full 72,453 catalog (infinite scroll, linked) + Boost search returns subsets (grasscloth 7715) -> NO dark-by-nav inventory, discoverability independent of per-collection nav links; c86 membership!=discoverable RESOLVED, 127k catch-all moot for reachability; honest limits (API facet-subset not confirmed; merchandising-depth unmeasured); closes collections/nav dark-inventory thread (April archive = only real vector)

ea0961175bcaa8f9ae6a6f8d61867e4f86af8f7b · 2026-06-18 09:35:50 -0700 · Steve Abrams

Files touched

Diff

commit ea0961175bcaa8f9ae6a6f8d61867e4f86af8f7b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jun 18 09:35:50 2026 -0700

    cycle 87: nav-link reachability (DTD unanimous A) — storefront runs Boost PFS; /collections/all Shop-All = full 72,453 catalog (infinite scroll, linked) + Boost search returns subsets (grasscloth 7715) -> NO dark-by-nav inventory, discoverability independent of per-collection nav links; c86 membership!=discoverable RESOLVED, 127k catch-all moot for reachability; honest limits (API facet-subset not confirmed; merchandising-depth unmeasured); closes collections/nav dark-inventory thread (April archive = only real vector)
---
 scripts/nav-link-reachability/FINDING.md           | 25 ++++++++++++++++++++++
 scripts/nav-link-reachability/PROBE-NOTES.md       | 18 ++++++++++++++++
 .../nav-link-reachability/navmenus-admin-probe.mjs | 24 +++++++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git a/scripts/nav-link-reachability/FINDING.md b/scripts/nav-link-reachability/FINDING.md
new file mode 100644
index 0000000..0bfc356
--- /dev/null
+++ b/scripts/nav-link-reachability/FINDING.md
@@ -0,0 +1,25 @@
+# Nav-link reachability: NO dark-by-nav inventory — Boost "Shop All" + site search reach the full 72,453-product catalog regardless of per-collection nav links — cycle 87
+
+**DTD verdict A (unanimous 3/3 — Claude + Codex + Qwen).** READ-ONLY (live storefront HTML fetch + the public Boost filter/search API + Admin GraphQL; no mutation), **$0**. Resolves the surface the c86 officer formally queued: "membership ≠ discoverable — a collection can be published + URL-reachable yet linked nowhere a shopper traverses." Both Codex and Qwen required testing whether a global filter/search (Boost) compensates for nav.
+
+## 🟢 Answer: discoverability does NOT depend on per-collection nav links — the storefront is a Boost Shop-All + search architecture that reaches the entire catalog
+- **The storefront runs Boost Product Filter & Search** (`services.mybcapps.com/bc-sf-filter/...`) — confirmed in the page JS (filter, search, search/products, search/suggest endpoints).
+- **`/collections/all` (Shop All) is Boost-powered with infinite scroll and contains the FULL catalog.** The public Boost filter API returns **`total_product: 72,453`** for the all-products scope (≈ the entire published catalog; cf. ~71,733 active scanned in c86). `/collections/all` is linked from the storefront.
+- **Boost site search is functional and returns proper subsets** — a query `q=grasscloth` returns **7,715 products** (a real subset of 72,453, not the flat list), proving search reaches products by term, not just the homepage.
+- **Top nav is HUB-based** (7 items): Brands → /pages/brands, Collections → /pages/collections, Color → /pages/shop-by-color, Material → /pages/shop-by-material, Styles → /pages/designer-wallpaper-styles, Commercial → /pages/commercial-wallcoverings, New Arrivals → /collections/new-arrivals — plus Shop All (/collections/all). Browse is organized as faceted hubs + a Boost-filtered Shop-All + search.
+
+## 🔬 The skeptical decode — this is the negative control the panel demanded
+- **The c86 caveat ("membership ≠ discoverable") was the right question; the answer is that the premise behind the dark-inventory worry doesn't hold here.** A product is "dark" only if NO shopper path reaches it. But every published product is in `/collections/all` (72,453), which is Boost-infinite-scroll + linked, AND reachable by Boost search. So per-collection nav-linking is NOT load-bearing for reachability.
+- **The c86 Flag-A concern is defused for REACHABILITY:** the unlinked 127k catch-all `best-seller-internal-use` doesn't matter for discoverability — Shop All + search reach products regardless. (Its feed-mislabel issue from c86 stands separately; this cycle is about reachability, not feed hygiene.)
+- **Negative control is a concrete external count, not a tautology:** the Boost API `total_product: 72,453` is measured from the same engine that powers the live storefront browse — it is the actual number a shopper can scroll/search, not an Admin-side membership count.
+
+## ⚠️ Honest limits (named, not papered over)
+1. **Faceted-filter subsetting not directly confirmed via the API:** my `filter_vendor=Thibaut` probe returned the full 72,453 (wrong Boost param name — Boost uses its own `pf_*`/`filter_*` schema), so I did NOT prove the on-page facet filters return subsets via the API. BUT Boost SEARCH returning 7,715 for "grasscloth" proves the same backend subsets correctly, and the storefront facet UI uses that engine — so faceted filtering is near-certain, just not API-confirmed this cycle.
+2. **Reachable ≠ well-merchandised (the softer residual, = c86 Flag A territory):** a product reachable ONLY via Shop All + search (not surfaced in a curated Brands/Color/Material/Styles hub facet) is reachable but poorly merchandised. The hub pages (/pages/brands etc.) are JS/linklist-rendered; I confirmed the 7 top-level hubs but did NOT enumerate every collection linked beneath them, so per-product MERCHANDISING-DEPTH (is each product in a curated facet, not just Shop-All) is unmeasured. That is a merchandising-quality question, NOT dark-inventory — separate, softer, lower priority.
+
+## 📋 Disposition: clean bill on dark-inventory reachability; no fix needed
+1. **No dark-by-nav inventory.** Every published product is reachable via Shop All (Boost infinite-scroll, 72,453) + Boost site search (proven). The c86 dark-inventory hypothesis is resolved: reachability does not hinge on per-collection nav-linking. No fix.
+2. **Together with c86 this closes the "dark inventory via collections/nav" thread:** c86 = 0 orphans (every product in ≥1 collection); c87 = every product reachable via Shop-All + search regardless of nav. The only genuine dark-inventory vector remains the April ARCHIVE (archived products, off-storefront) — a separate, already-tracked campaign.
+3. **Residuals (named, queued):** (a) merchandising-DEPTH — are products in curated hub facets, not just Shop-All (softer, c86 Flag-A adjacent); (b) IMAGE integrity (Qwen's c86/c87 dissent — missing featured image / 404 CDN) still UNSWEPT; (c) inventory=2026 still un-audited.
+
+_Cycle 87. DTD-picked A (unanimous 3/3). Resolved the c86-officer-queued nav-link reachability question: the storefront runs Boost Product Filter & Search; `/collections/all` (Shop All, linked, infinite-scroll) contains the full 72,453-product catalog per the public Boost API, and Boost site search returns proper subsets (grasscloth → 7,715). So discoverability does NOT depend on per-collection nav links → NO dark-by-nav inventory; the c86 "membership ≠ discoverable" concern is resolved and the unlinked 127k catch-all is moot for reachability. Honest limits named: API faceted-filter subsetting not directly confirmed (search proven instead); merchandising-DEPTH (curated-facet vs Shop-All-only) unmeasured = a separate softer residual. Together with c86 this closes the collections/nav dark-inventory thread; the April archive remains the only real dark-inventory vector (separate campaign). PJ excluded. Read-only, $0, no fix gated._
diff --git a/scripts/nav-link-reachability/PROBE-NOTES.md b/scripts/nav-link-reachability/PROBE-NOTES.md
new file mode 100644
index 0000000..efdf14f
--- /dev/null
+++ b/scripts/nav-link-reachability/PROBE-NOTES.md
@@ -0,0 +1,18 @@
+# nav-link-reachability probes (cycle 87, READ-ONLY, $0)
+
+Admin GraphQL `menus` field = ACCESS_DENIED (token lacks read_online_store_navigation).
+Pivoted to public storefront + Boost API (read-only GETs):
+
+1. Live nav (homepage HTML parse): 7 hub-based top items — Brands/Collections/Color/
+   Material/Styles/Commercial/New Arrivals (+ Shop All /collections/all linked in body).
+2. Boost Product Filter & Search confirmed (services.mybcapps.com/bc-sf-filter/*).
+3. Boost filter API for /collections/all scope:  total_product = 72,453 (full catalog).
+4. Boost search q=grasscloth: total_product = 7,715 (proper subset → search works).
+5. filter_vendor=Thibaut probe returned full 72,453 = WRONG param name (Boost uses its own
+   pf_*/filter_* schema) → faceted-filter API subsetting NOT directly confirmed (search proven instead).
+
+Commands (no creds; public Boost endpoint + public storefront):
+  curl --compressed "https://designerwallcoverings.com/"
+  curl --compressed "https://designerwallcoverings.com/collections/all"
+  curl --compressed "https://services.mybcapps.com/bc-sf-filter/filter?shop=designer-laboratory-sandbox.myshopify.com&limit=1&page=1"
+  curl --compressed "https://services.mybcapps.com/bc-sf-filter/search?shop=designer-laboratory-sandbox.myshopify.com&q=grasscloth&limit=1"
diff --git a/scripts/nav-link-reachability/navmenus-admin-probe.mjs b/scripts/nav-link-reachability/navmenus-admin-probe.mjs
new file mode 100644
index 0000000..1a74b69
--- /dev/null
+++ b/scripts/nav-link-reachability/navmenus-admin-probe.mjs
@@ -0,0 +1,24 @@
+import fs from 'fs';
+const ENV=fs.readFileSync('/Users/stevestudio2/Projects/secrets-manager/.env','utf8');
+const TOK=((ENV.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1]||'').replace(/['"\r]/g,'').trim();
+const GQL='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+async function gql(q,v){const r=await fetch(GQL,{method:'POST',headers:{'X-Shopify-Access-Token':TOK,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});return r.json();}
+// Admin GraphQL menus connection (online store navigation)
+const q=`{ menus(first:30){ edges{ node{ handle title
+  items{ title type url resourceId
+    items{ title type url resourceId
+      items{ title type url resourceId } } } } } } }`;
+const j=await gql(q,{});
+if(j.errors){ console.log("ERRORS:",JSON.stringify(j.errors)); process.exit(0); }
+const collHandles=new Set(); const linkTypes={};
+function walk(items){ for(const it of (items||[])){ linkTypes[it.type]=(linkTypes[it.type]||0)+1;
+  const m=(it.url||'').match(/\/collections\/([^\/?#]+)/); if(m) collHandles.add(m[1]);
+  if(it.type==='COLLECTION' && it.resourceId) collHandles.add('gid:'+it.resourceId);
+  walk(it.items); } }
+const menus=j.data.menus.edges.map(e=>e.node);
+console.log("MENUS:", menus.map(m=>`${m.handle}("${m.title}", menu)`).join(' | '));
+menus.forEach(m=>walk(m.items));
+console.log("\nlink types:", JSON.stringify(linkTypes));
+console.log("\ncollection handles linked in nav ("+collHandles.size+"):");
+console.log([...collHandles].sort().join('\n'));
+fs.writeFileSync('/tmp/nav-linked-collections.json',JSON.stringify({ts:'2026-06-18',menus:menus.map(m=>({handle:m.handle,title:m.title,itemsCount:m.itemsCount})),linkedHandles:[...collHandles]},null,2));

← 7a5788f cycle 86: consistency fix — closing line reflects Flag A upg  ·  back to Dw Yolo Loop  ·  cycle 87: officer vp-dw-marketing CONFIRMED + scope tighteni 4ca0d91 →