@piercebarney/whs-eleventy 2026.9.30 → 2026.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/compliance.js CHANGED
@@ -18,7 +18,7 @@ const path = require("node:path");
18
18
  const { execSync } = require("node:child_process");
19
19
  const { parse: parseHtml } = require("node-html-parser");
20
20
  const { runRepoChecks } = require("./doctor.js");
21
- const { ROOT, resolveStandard } = require("./_project.js");
21
+ const { ROOT, resolveStandard, tryProjectRequire } = require("./_project.js");
22
22
 
23
23
  const SITE = path.join(ROOT, "_site");
24
24
  const CACHE = path.join(ROOT, ".cache", "compliance.json");
@@ -467,11 +467,36 @@ const CHECKS = {
467
467
  // The privacy page may be a standalone src/privacy.njk or a pages.json
468
468
  // entry rendered by a src/pages/ shell — check the built output, with a
469
469
  // source fallback for when _site isn't built yet.
470
- const built = has("_site/privacy/index.html") || has("_site/privacy.html");
470
+ const builtPath = has("_site/privacy/index.html")
471
+ ? "_site/privacy/index.html"
472
+ : has("_site/privacy.html")
473
+ ? "_site/privacy.html"
474
+ : null;
471
475
  const source =
472
476
  has("src/privacy.njk") ||
473
477
  /["']slug["']\s*:\s*["']privacy["']/.test(read("src/content/pages.json") || "");
474
- if (!built && !source) return { status: FAIL, note: "no privacy page" };
478
+ if (!builtPath && !source) return { status: FAIL, note: "no privacy page" };
479
+
480
+ // Prefer checking the built page's own rendered HTML for every declared
481
+ // third party's name — what a user actually sees, independent of which
482
+ // source file or templating approach produced it. Falls back to the
483
+ // source-level pattern only when there's no built output yet, or
484
+ // nothing declared to check against.
485
+ if (builtPath) {
486
+ const thirdparties = tryProjectRequire("src/_data/thirdparties.js", null);
487
+ if (Array.isArray(thirdparties) && thirdparties.length) {
488
+ const html = read(builtPath) || "";
489
+ const missing = thirdparties
490
+ .filter((t) => t?.name && !html.includes(t.name))
491
+ .map((t) => t.name);
492
+ return missing.length
493
+ ? { status: FAIL, note: `privacy page missing disclosure for: ${missing.join(", ")}` }
494
+ : {
495
+ status: PASS,
496
+ note: "privacy page present; built output discloses every declared third party",
497
+ };
498
+ }
499
+ }
475
500
  // The third-party disclosure must be generated from _data/thirdparties.js,
476
501
  // never hand-maintained — the loop lives in the privacy shell or an include.
477
502
  if (!hasThirdPartyLoop())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piercebarney/whs-eleventy",
3
- "version": "2026.9.30",
3
+ "version": "2026.10.2",
4
4
  "description": "The web house style's Eleventy + Netlify tooling — the compliance sweep, the infra doctor, the link/CSP integrity check, and the a11y scan, shared by every project on the stack.",
5
5
  "bin": {
6
6
  "whs": "cli.js"
@@ -21,6 +21,54 @@ enforced, new *opt-in* chapters/capabilities, tooling-only changes — is
21
21
 
22
22
  ---
23
23
 
24
+ ## 2026-10-02 [non-breaking]
25
+
26
+ ### templates/commands
27
+
28
+ `/whs:adopt` never created or seeded `src/_data/dashboard.js` — the
29
+ committed one-time-setup checklist `whs status --hook`'s `SessionStart`
30
+ nudge reads (GitHub secrets, `netlify link`, Search Console, Bing, HTTPS).
31
+ Because the file never existed for an adopted project, `pendingDashboardCount()`
32
+ silently returned `0` — the exact mechanism that let this go unnoticed,
33
+ since the reminder looked satisfied rather than obviously broken. Step 5's
34
+ Eleventy branch now seeds the same seven items `bin/init`'s `seedDashboard()`
35
+ produces for a freshly-scaffolded project, byte-identical, prepending the
36
+ two setup-specific items ahead of the five observability items the template
37
+ ships; a conflict guard leaves an existing `dashboard.js` untouched. Third
38
+ `/whs:adopt`-vs-`/whs:new` parity gap found this week, after agent-delegation
39
+ setup and, separately, the still-open build/serve scripts gap. Found directly
40
+ in an adopting session's report — no `feedback/` file exists for this one.
41
+ Fixed in `a4c7ba6`.
42
+
43
+ ---
44
+
45
+ ## 2026-10-01 [non-breaking]
46
+
47
+ ### packages/whs-eleventy
48
+
49
+ Supersedes yesterday's (2026-09-30) `hasThirdPartyLoop()` widening, which was
50
+ correct but unreachable: the standard's own reference `audit.njk` template
51
+ independently contains a matching loop pattern for its unrelated Content &
52
+ Links tab, so `privacy`'s broad source scan always found that coincidental
53
+ match first, before the new fallback logic could ever run — this affected
54
+ every project descended from the template, not just the one that reported
55
+ it. `privacy` in `lib/compliance.js` now checks the built privacy page's own
56
+ rendered HTML for every third party declared in `src/_data/thirdparties.js`,
57
+ by name — what a user actually sees, independent of which source file or
58
+ templating syntax produced it — falling back to yesterday's source-pattern
59
+ mechanism (unchanged, still present) only when there's no built output yet
60
+ or nothing is declared to check against. Confirmed against the reference
61
+ template itself: `privacy` still PASSes, now for the correct reason (built
62
+ output discloses every declared party) instead of the coincidental
63
+ `audit.njk` match. Resolves
64
+ `feedback/2026-09-23-privacy-thirdparty-check-scans-wrong-file.md` (the
65
+ original report) and
66
+ `feedback/2026-09-24-privacy-thirdparty-fix-still-short-circuits-on-audit-loop.md`
67
+ (the follow-up that diagnosed why the 2026-09-30 fix didn't work). Fixed in
68
+ `56f5c67`.
69
+
70
+ ---
71
+
24
72
  ## 2026-09-30 [non-breaking]
25
73
 
26
74
  ### packages/whs-eleventy
package/standard/core.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Web project house style — CORE (stack-agnostic)
2
2
 
3
- **Version:** 2026-09-30 · **Status:** active
3
+ **Version:** 2026-10-02 · **Status:** active
4
4
 
5
5
  This is the stack-agnostic contract every web project follows, regardless of
6
6
  framework, host, or CSS system. It says **what** must be true, with concrete
@@ -1467,7 +1467,7 @@ governs it and follow that chapter — the slugs are the index (a `<script>` →
1467
1467
  - production-url: https://example.com
1468
1468
  - content-type: tool # tool | article (article => feeds)
1469
1469
  - publishing-rate: ~5 pages/week
1470
- - standard-version: 2026-09-30 # recommended — enables standard-version drift tracking (#compliance)
1470
+ - standard-version: 2026-10-02 # recommended — enables standard-version drift tracking (#compliance)
1471
1471
  ```
1472
1472
 
1473
1473
  If the section is absent, the assistant's first action is to run the flow above