[object Object]

← back to Homesonspec

fix(homesonspec): berkeley-building — real self-card isolation test + status docs (TK-10487 Cody gate)

235736eb34fd91113481185932b0d18093e56b01 · 2026-08-30 21:06:30 -0700 · Steve

Cody confirmed the extraction is CORRECT (exact-path self-card status does not
cross-contaminate siblings; no fabrication; garage/lot genuinely absent; ids
distinct) but flagged test-quality holes:
- The sibling-isolation test was a DECOY — it proved isolation only against a
  NONEXISTENT path. Replaced with a same-page multi-path test (home-08): each real
  sibling path resolves to its OWN card's verified label+status (2069 -> Available
  December 2026/UNDER_CONSTRUCTION vs 2079 -> Model Home/MOVE_IN_READY on the SAME
  html) — genuine exact-path isolation. Proven to FAIL when the match is loosened
  (it then grabs the first card). It also exercises the Pending->null +
  Available<Month>/Under-Construction + Quick-Move-In/Model branches END-TO-END,
  which no PRIMARY-home fixture triggers.
- Documented the "Model Home -> MOVE_IN_READY with price=null" semantic tension
  (constructionStatus claim, NOT sales-availability) so downstream never renders it
  as "for sale now".
- Documented the HomeCard__status immediate-child platform assumption (a break is a
  LOUD cov.status===n failure, not a silent mislabel).

tsc 0; vitest 11/11. Local build/test only; ingest/seed/deploy gated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 235736eb34fd91113481185932b0d18093e56b01
Author: Steve <steve@designerwallcoverings.com>
Date:   Sun Aug 30 21:06:30 2026 -0700

    fix(homesonspec): berkeley-building — real self-card isolation test + status docs (TK-10487 Cody gate)
    
    Cody confirmed the extraction is CORRECT (exact-path self-card status does not
    cross-contaminate siblings; no fabrication; garage/lot genuinely absent; ids
    distinct) but flagged test-quality holes:
    - The sibling-isolation test was a DECOY — it proved isolation only against a
      NONEXISTENT path. Replaced with a same-page multi-path test (home-08): each real
      sibling path resolves to its OWN card's verified label+status (2069 -> Available
      December 2026/UNDER_CONSTRUCTION vs 2079 -> Model Home/MOVE_IN_READY on the SAME
      html) — genuine exact-path isolation. Proven to FAIL when the match is loosened
      (it then grabs the first card). It also exercises the Pending->null +
      Available<Month>/Under-Construction + Quick-Move-In/Model branches END-TO-END,
      which no PRIMARY-home fixture triggers.
    - Documented the "Model Home -> MOVE_IN_READY with price=null" semantic tension
      (constructionStatus claim, NOT sales-availability) so downstream never renders it
      as "for sale now".
    - Documented the HomeCard__status immediate-child platform assumption (a break is a
      LOUD cov.status===n failure, not a silent mislabel).
    
    tsc 0; vitest 11/11. Local build/test only; ingest/seed/deploy gated.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 collectors/berkeley-building/src/index.ts         | 12 +++++++++
 collectors/berkeley-building/src/selftest.test.ts | 30 ++++++++++++++++-------
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/collectors/berkeley-building/src/index.ts b/collectors/berkeley-building/src/index.ts
index 4bac5230..69970bd6 100644
--- a/collectors/berkeley-building/src/index.ts
+++ b/collectors/berkeley-building/src/index.ts
@@ -222,6 +222,11 @@ export function statusFromLabel(label: string | null): "PLANNED" | "UNDER_CONSTR
   const p = label.toLowerCase();
   // "Pending" is a sale state, not a construction stage → honest null.
   if (p.includes("pending")) return null;
+  // NOTE (TK-10487 Cody): "Model Home" -> MOVE_IN_READY is a CONSTRUCTION-status
+  // claim (the home is complete + standing), NOT a sales-availability claim — the
+  // 4 model homes in the sample carry price=null. A downstream consumer must not
+  // render "MOVE_IN_READY + no price" as "for sale now"; the field is
+  // constructionStatus, and price=null is the honest "not listed for sale" signal.
   if (
     p.includes("move-in") ||
     p.includes("move in") ||
@@ -259,6 +264,13 @@ function zipConsistentWithState(zip: string | null, state: string | null): boole
  * THIS page's own detail path carries the authoritative status in its
  * <div class="HomeCard__status">. We match on the exact self-path so a sibling
  * card can never leak its status onto the primary home. Returns the raw phrase.
+ *
+ * PLATFORM ASSUMPTION (TK-10487 Cody): this assumes HomeCard__status is the
+ * IMMEDIATE first child of the anchor (the current Clayton React-SSR output). If
+ * that platform ever wraps the status in an intermediate element, this drops to
+ * null on ALL homes — a LOUD failure the selftest's `cov.status === n` catches,
+ * not a silent mislabel. Isolation is verified by the same-page distinct-status
+ * test in selftest.test.ts.
  */
 export function selfCardStatusLabel(html: string, selfPath: string): string | null {
   if (!selfPath) return null;
diff --git a/collectors/berkeley-building/src/selftest.test.ts b/collectors/berkeley-building/src/selftest.test.ts
index 04aecf6d..a3773cc8 100644
--- a/collectors/berkeley-building/src/selftest.test.ts
+++ b/collectors/berkeley-building/src/selftest.test.ts
@@ -278,16 +278,28 @@ describe("berkeley-building adapter — coverage + per-home + honest-nulls + sch
     expect(strippedHome?.street, "null-status home still needs a real street").toBeTruthy();
   });
 
-  it("selfCardStatusLabel matches the home's OWN card, not a sibling card", () => {
-    // home-08's self-path status is "Available December 2026"; a sibling path on
-    // the same page (2079… the model home) must NOT leak its "Model Home" status
-    // into the primary home.
+  it("selfCardStatusLabel is isolated per home path (no sibling leak) + covers every status branch end-to-end", () => {
+    // Cody catch: the old test proved isolation only against a NONEXISTENT path —
+    // a decoy. This drives REAL sibling card paths on ONE captured community-grid
+    // page (home-08) so each path resolves to its OWN card's label + status. Same
+    // page, different paths, DIFFERENT verified statuses = genuine exact-path
+    // isolation. It also exercises the Pending->null and Available<Month>/Under-
+    // Construction branches END-TO-END (no captured PRIMARY home is Pending/PLANNED,
+    // so the fixture would otherwise never drive those paths through parseHome).
     const html = readFileSync(join(FX, "home-08.html"), "utf8");
-    expect(selfCardStatusLabel(html, "/homes/meridian/lavender-place/2069-e-deep-purple-ln")).toBe(
-      "Available December 2026",
-    );
-    // A path that isn't on the page → null (never a stray sibling).
-    expect(selfCardStatusLabel(html, "/homes/nowhere/none/0-nope")).toBeNull();
+    const cases: [string, string | null, string | null][] = [
+      // [path, expected raw card label, expected mapped status]
+      ["/homes/meridian/lavender-place/2069-e-deep-purple-ln", "Available December 2026", "UNDER_CONSTRUCTION"], // self
+      ["/homes/meridian/oaklawn/8209-w-gallup-st", "Model Home", "MOVE_IN_READY"], // sibling
+      ["/homes/caldwell/solstice/3405-elliptical-ln", "Quick Move-In!", "MOVE_IN_READY"], // sibling
+      ["/homes/eagle/valnova/6480-w-sollas-ct", "Under Construction", "UNDER_CONSTRUCTION"], // sibling
+      ["/homes/undefined/undefined/1485-e-andes-dr", "Pending", null], // sibling — Pending -> honest null
+      ["/homes/nowhere/none/0-nope", null, null], // absent path -> null (never a stray sibling)
+    ];
+    for (const [path, label, status] of cases) {
+      expect(selfCardStatusLabel(html, path), `card label for ${path}`).toBe(label);
+      expect(statusFromLabel(selfCardStatusLabel(html, path)), `mapped status for ${path}`).toBe(status);
+    }
   });
 
   it("statusFromLabel maps every branch — no dead MOVE_IN_READY/UNDER_CONSTRUCTION/PLANNED code", () => {

← 6343338a test(homesonspec): wire ops/*.test.mjs into npm test — snaps  ·  back to Homesonspec  ·  ops(homesonspec): read-only offload PREFLIGHT GO/NO-GO — des bab4fd97 →