stylegallery 0.1.0 → 0.1.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.
Files changed (230) hide show
  1. package/AGENTS.md +4 -1
  2. package/DOMAINS.md +2 -6
  3. package/GOVERNANCE.md +10 -9
  4. package/README.md +29 -127
  5. package/consumer-reference/agent-native/v2/admission-policy.json +646 -0
  6. package/consumer-reference/agent-native/v2/material-registry.json +1 -0
  7. package/consumer-reference/agent-native/v2/schema/admission-policy.schema.json +50 -0
  8. package/consumer-reference/agent-native/v2/schema/material-manifest.schema.json +17 -0
  9. package/consumer-reference/agent-native/v2/schema/material-record.schema.json +20 -0
  10. package/consumer-reference/contract.md +1 -1
  11. package/consumer-reference/index.md +5 -3
  12. package/layout/index.md +124 -0
  13. package/log.md +57 -0
  14. package/package.json +183 -22
  15. package/scripts/agent-native/v2/experimental-extension-registry.mjs +143 -0
  16. package/scripts/agent-native/v2/extensions/a2a-projection.mjs +264 -0
  17. package/scripts/agent-native/v2/extensions/agui-projection.mjs +191 -0
  18. package/scripts/agent-native/v2/material-admission.mjs +295 -0
  19. package/scripts/agent-native/v2/material-cli-adapter.mjs +134 -0
  20. package/scripts/agent-native/v2/material-context.mjs +251 -0
  21. package/scripts/agent-native/v2/material-identity.mjs +71 -0
  22. package/scripts/agent-native/v2/material-mcp-adapter.mjs +253 -0
  23. package/scripts/agent-native/v2/material-operation-registry.mjs +123 -0
  24. package/scripts/agent-native/v2/material-queries.mjs +398 -0
  25. package/scripts/agent-native/v2/material-registry.mjs +319 -0
  26. package/scripts/sg-material-mcp.mjs +98 -0
  27. package/scripts/sg-material.mjs +27 -0
  28. package/consumer-reference/adapters/style-dictionary.config.mjs +0 -36
  29. package/consumer-reference/baselines/calibration.json +0 -260
  30. package/consumer-reference/baselines/manifest.json +0 -21
  31. package/consumer-reference/fixtures/consumer-conformance/e2e-fixture.mjs +0 -282
  32. package/consumer-reference/fixtures/consumer-conformance/manifest.json +0 -102
  33. package/consumer-reference/fixtures/consumer-conformance/runtime-proof.mjs +0 -32
  34. package/consumer-reference/fixtures/consumer-conformance/valid-migration-result.json +0 -18
  35. package/consumer-reference/fixtures/consumer-conformance/valid-migration.json +0 -142
  36. package/consumer-reference/fixtures/invalid-stable-ended-support.json +0 -19
  37. package/consumer-reference/fixtures/promotion/invalid-blocking-evidence.json +0 -26
  38. package/consumer-reference/fixtures/promotion/invalid-count-only.json +0 -29
  39. package/consumer-reference/fixtures/promotion/invalid-missing-owner-migration.json +0 -25
  40. package/consumer-reference/fixtures/promotion/invalid-normative-bypass-no-regression.json +0 -25
  41. package/consumer-reference/fixtures/promotion/invalid-related-counted-independent.json +0 -45
  42. package/consumer-reference/fixtures/promotion/invalid-stable-ended-support.json +0 -26
  43. package/consumer-reference/fixtures/promotion/manifest.json +0 -15
  44. package/consumer-reference/fixtures/promotion/valid-deferred-example.json +0 -67
  45. package/consumer-reference/fixtures/promotion/valid-normative-bypass.json +0 -67
  46. package/consumer-reference/fixtures/token-portability/invalid-cycle.json +0 -7
  47. package/consumer-reference/fixtures/token-portability/invalid-dangling-alias.json +0 -6
  48. package/consumer-reference/fixtures/token-portability/invalid-extends.json +0 -4
  49. package/consumer-reference/fixtures/token-portability/invalid-json-pointer.json +0 -7
  50. package/consumer-reference/fixtures/token-portability/invalid-resolver.json +0 -9
  51. package/consumer-reference/fixtures/token-portability/invalid-type-mismatch.json +0 -10
  52. package/consumer-reference/fixtures/token-portability/invalid-unknown-reserved.json +0 -6
  53. package/consumer-reference/fixtures/token-portability/invalid-untested-type.json +0 -6
  54. package/consumer-reference/fixtures/token-portability/valid-border.json +0 -14
  55. package/consumer-reference/fixtures/token-portability/valid-reference.json +0 -32
  56. package/consumer-reference/fixtures/token-portability/valid-whole-alias.json +0 -7
  57. package/consumer-reference/fixtures/valid-deprecated.json +0 -21
  58. package/consumer-reference/fixtures/valid-experimental.json +0 -19
  59. package/consumer-reference/generated/manifest.json +0 -40
  60. package/consumer-reference/generated/tokens.css +0 -12
  61. package/consumer-reference/policies/shared-experimental.json +0 -37
  62. package/consumer-reference/schema/ax-evidence.schema.json +0 -30
  63. package/consumer-reference/schema/baseline-manifest.schema.json +0 -55
  64. package/consumer-reference/schema/calibration-record.schema.json +0 -190
  65. package/consumer-reference/schema/capture-session.schema.json +0 -161
  66. package/consumer-reference/schema/component-state.schema.json +0 -150
  67. package/consumer-reference/schema/consumer-conformance-record.schema.json +0 -365
  68. package/consumer-reference/schema/dom-evidence.schema.json +0 -38
  69. package/consumer-reference/schema/evidence-record.schema.json +0 -81
  70. package/consumer-reference/schema/fixture-manifest.schema.json +0 -32
  71. package/consumer-reference/schema/item.schema.json +0 -188
  72. package/consumer-reference/schema/page-evidence-manifest.schema.json +0 -216
  73. package/consumer-reference/schema/page-evidence-session.schema.json +0 -119
  74. package/consumer-reference/schema/portable-tokens.schema.json +0 -104
  75. package/consumer-reference/schema/promotion-rfc.schema.json +0 -219
  76. package/consumer-reference/schema/runtime-evidence-manifest.schema.json +0 -33
  77. package/consumer-reference/schema/visual-evidence.schema.json +0 -31
  78. package/design-engineering/consumer-migration-readiness.md +0 -124
  79. package/design-engineering/interface-craft.md +0 -107
  80. package/design-engineering/reference-profiles/external-adaptation/index.md +0 -12
  81. package/design-engineering/reference-profiles/governed-local/editorial/components/button.component.json +0 -125
  82. package/design-engineering/reference-profiles/governed-local/editorial/evidence/button.evidence.json +0 -3504
  83. package/design-engineering/reference-profiles/governed-local/editorial/fixtures/button.fixture.json +0 -65
  84. package/design-engineering/reference-profiles/governed-local/editorial/generated/evidence-coverage.md +0 -23
  85. package/design-engineering/reference-profiles/governed-local/editorial/generated/keyboard-matrix.md +0 -19
  86. package/design-engineering/reference-profiles/governed-local/editorial/generated/state-matrix.md +0 -21
  87. package/design-engineering/reference-profiles/governed-local/editorial/local-foundations.json +0 -12
  88. package/design-engineering/reference-profiles/governed-local/editorial/states/button.states.json +0 -195
  89. package/design-engineering/reference-profiles/governed-local/editorial/tokens.dtcg.json +0 -17
  90. package/design-engineering/reference-profiles/governed-local/terminal/components/button.component.json +0 -125
  91. package/design-engineering/reference-profiles/governed-local/terminal/evidence/button.evidence.json +0 -3504
  92. package/design-engineering/reference-profiles/governed-local/terminal/fixtures/button.fixture.json +0 -65
  93. package/design-engineering/reference-profiles/governed-local/terminal/generated/evidence-coverage.md +0 -23
  94. package/design-engineering/reference-profiles/governed-local/terminal/generated/keyboard-matrix.md +0 -19
  95. package/design-engineering/reference-profiles/governed-local/terminal/generated/state-matrix.md +0 -21
  96. package/design-engineering/reference-profiles/governed-local/terminal/local-foundations.json +0 -12
  97. package/design-engineering/reference-profiles/governed-local/terminal/profile.json +0 -43
  98. package/design-engineering/reference-profiles/governed-local/terminal/states/button.states.json +0 -195
  99. package/design-engineering/reference-profiles/governed-local/terminal/tokens.dtcg.json +0 -17
  100. package/game-ui/classification.md +0 -82
  101. package/game-ui/reference-record.md +0 -62
  102. package/game-ui/screen-hierarchy.md +0 -107
  103. package/game-ui/unity/architecture.md +0 -166
  104. package/game-ui/unity/cli-loop.md +0 -84
  105. package/game-ui/unity/data/unity-technologies-public-repositories.json +0 -26654
  106. package/game-ui/unity/org-wiki.md +0 -146
  107. package/game-ui/unity/repository-map.md +0 -102
  108. package/game-ui/unity/ui-systems.md +0 -85
  109. package/motion/practice-reference.md +0 -145
  110. package/motion/review-workflow.md +0 -86
  111. package/motion/vocabulary.md +0 -82
  112. package/platform-guides/apple-interaction.md +0 -89
  113. package/scripts/agent-native/events.mjs +0 -113
  114. package/scripts/agent-native/immutable-store.mjs +0 -102
  115. package/scripts/artifact-metadata.mjs +0 -20
  116. package/scripts/audit-evidence-freshness.mjs +0 -308
  117. package/scripts/baseline-contract.mjs +0 -189
  118. package/scripts/baseline-schema-parity.mjs +0 -40
  119. package/scripts/build-reference-artifacts.mjs +0 -127
  120. package/scripts/calibration-raw-contract.mjs +0 -172
  121. package/scripts/capture-session-contract.mjs +0 -187
  122. package/scripts/component-state-artifact-fixture.mjs +0 -44
  123. package/scripts/component-state-contract.mjs +0 -99
  124. package/scripts/component-state-semantics.mjs +0 -128
  125. package/scripts/component-state-workflow-contract.mjs +0 -67
  126. package/scripts/component-state-workflow-negative-cases.mjs +0 -64
  127. package/scripts/consumer-conformance-contract.mjs +0 -198
  128. package/scripts/consumer-evidence-governance-contract.mjs +0 -210
  129. package/scripts/consumer-reference-case-runner.mjs +0 -93
  130. package/scripts/consumer-reference-schema.mjs +0 -155
  131. package/scripts/create-component-state-session.mjs +0 -100
  132. package/scripts/create-page-evidence-session.mjs +0 -139
  133. package/scripts/domain-document-boundaries.mjs +0 -40
  134. package/scripts/domain-validation-checks.mjs +0 -141
  135. package/scripts/evidence-artifact-contract.mjs +0 -191
  136. package/scripts/finalize-component-state-evidence.mjs +0 -165
  137. package/scripts/finalize-page-evidence.mjs +0 -197
  138. package/scripts/generate-consumer-reference-evidence.mjs +0 -154
  139. package/scripts/generate-patterns.mjs +0 -218
  140. package/scripts/governance-matrix-contract.mjs +0 -73
  141. package/scripts/governance-matrix-negative-cases.mjs +0 -114
  142. package/scripts/governance-policy-contract.mjs +0 -49
  143. package/scripts/governance-test-fixture.mjs +0 -321
  144. package/scripts/governance-workflow-negative-cases.mjs +0 -241
  145. package/scripts/governed-profile-registry.mjs +0 -125
  146. package/scripts/json-schema-formats.mjs +0 -31
  147. package/scripts/markdown-structure.mjs +0 -45
  148. package/scripts/page-artifact-metadata.mjs +0 -124
  149. package/scripts/page-evidence-contract.mjs +0 -297
  150. package/scripts/page-evidence-fixture.mjs +0 -271
  151. package/scripts/pattern-data.mjs +0 -325
  152. package/scripts/profile-record-contract.mjs +0 -140
  153. package/scripts/promotion-attestation-contract.mjs +0 -91
  154. package/scripts/promotion-boundary-test-contract.mjs +0 -92
  155. package/scripts/promotion-fixture-inventory.mjs +0 -109
  156. package/scripts/promotion-governance-contract.mjs +0 -28
  157. package/scripts/reference-artifact-path-contract.mjs +0 -28
  158. package/scripts/reference-profile-contract.mjs +0 -114
  159. package/scripts/reference-token-contract.mjs +0 -156
  160. package/scripts/run-consumer-page-evidence-ci.mjs +0 -170
  161. package/scripts/summarize-sentinel-calibration.mjs +0 -98
  162. package/scripts/test-agent-adapter-conformance.mjs +0 -250
  163. package/scripts/test-agent-conformance-receipt.mjs +0 -106
  164. package/scripts/test-agent-events.mjs +0 -81
  165. package/scripts/test-agent-execution-effects.mjs +0 -114
  166. package/scripts/test-agent-execution-fixtures.mjs +0 -140
  167. package/scripts/test-agent-execution-kernel.mjs +0 -39
  168. package/scripts/test-agent-execution-learning.mjs +0 -130
  169. package/scripts/test-agent-execution-lifecycle.mjs +0 -143
  170. package/scripts/test-agent-execution-safety.mjs +0 -158
  171. package/scripts/test-agent-execution-views.mjs +0 -117
  172. package/scripts/test-agent-identity-integrity-cases.mjs +0 -160
  173. package/scripts/test-agent-knowledge-kernel.mjs +0 -183
  174. package/scripts/test-agent-learning.mjs +0 -246
  175. package/scripts/test-agent-mcp.mjs +0 -246
  176. package/scripts/test-agent-native-schemas.mjs +0 -215
  177. package/scripts/test-agent-projections.mjs +0 -249
  178. package/scripts/test-agent-registry-mcp-integrity.mjs +0 -215
  179. package/scripts/test-agent-registry-mutations.mjs +0 -110
  180. package/scripts/test-audit-evidence-freshness.mjs +0 -177
  181. package/scripts/test-component-state-sentinel.mjs +0 -35
  182. package/scripts/test-component-state-source-contract.mjs +0 -83
  183. package/scripts/test-consumer-conformance-sentinel.mjs +0 -165
  184. package/scripts/test-consumer-reference-sentinel.mjs +0 -31
  185. package/scripts/test-generate-consumer-reference-evidence.mjs +0 -124
  186. package/scripts/test-json-cli-output.mjs +0 -151
  187. package/scripts/test-json-schema-formats.mjs +0 -40
  188. package/scripts/test-reference-adapters.mjs +0 -199
  189. package/scripts/test-renderer-purity.mjs +0 -34
  190. package/scripts/test-sg-cli.mjs +0 -129
  191. package/scripts/test-summarize-sentinel-calibration.mjs +0 -226
  192. package/scripts/test-validate-baseline-manifest.mjs +0 -234
  193. package/scripts/test-validate-component-state-artifacts.mjs +0 -243
  194. package/scripts/test-validate-component-state.mjs +0 -106
  195. package/scripts/test-validate-consumer-conformance.mjs +0 -427
  196. package/scripts/test-validate-consumer-reference-cli.mjs +0 -69
  197. package/scripts/test-validate-consumer-reference.mjs +0 -263
  198. package/scripts/test-validate-domains.mjs +0 -357
  199. package/scripts/test-validate-governance.mjs +0 -292
  200. package/scripts/test-validate-ia.mjs +0 -262
  201. package/scripts/test-validate-okf.mjs +0 -73
  202. package/scripts/test-validate-page-evidence.mjs +0 -302
  203. package/scripts/test-validate-patterns.mjs +0 -157
  204. package/scripts/test-validate-promotion-rfc.mjs +0 -250
  205. package/scripts/test-validate-reference-profiles.mjs +0 -170
  206. package/scripts/test-validate-unity-org-wiki.mjs +0 -57
  207. package/scripts/test-validate-unity-source-contracts.mjs +0 -67
  208. package/scripts/test-validate-vocabulary.mjs +0 -174
  209. package/scripts/test-validate-webpage-workflow.mjs +0 -293
  210. package/scripts/validate-baseline-manifest.mjs +0 -44
  211. package/scripts/validate-catalog.mjs +0 -65
  212. package/scripts/validate-component-state.mjs +0 -141
  213. package/scripts/validate-consumer-conformance.mjs +0 -477
  214. package/scripts/validate-consumer-reference.mjs +0 -288
  215. package/scripts/validate-domains.mjs +0 -237
  216. package/scripts/validate-governance.mjs +0 -248
  217. package/scripts/validate-ia.mjs +0 -136
  218. package/scripts/validate-links.mjs +0 -66
  219. package/scripts/validate-okf.mjs +0 -104
  220. package/scripts/validate-page-evidence.mjs +0 -191
  221. package/scripts/validate-patterns.mjs +0 -246
  222. package/scripts/validate-promotion-rfc.mjs +0 -224
  223. package/scripts/validate-reference-artifacts.mjs +0 -125
  224. package/scripts/validate-renderer-purity.mjs +0 -56
  225. package/scripts/validate-unity-org-wiki.mjs +0 -146
  226. package/scripts/validate-unity-source-contracts.mjs +0 -107
  227. package/scripts/validate-vocabulary.mjs +0 -115
  228. package/scripts/validate-webpage-workflow.mjs +0 -254
  229. package/scripts/visual-expectation-contract.mjs +0 -20
  230. package/scripts/workflow-action-contract.mjs +0 -163
@@ -1,292 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
- import { spawnSync } from "node:child_process";
7
- import { fileURLToPath } from "node:url";
8
- import { files, generatedWarning, sentinelProvenanceClauses } from "./governance-test-fixture.mjs";
9
- import { governanceMatrixCases } from "./governance-matrix-negative-cases.mjs";
10
- import { componentStateWorkflowCases } from "./component-state-workflow-negative-cases.mjs";
11
- import { workflowSafetyCases } from "./governance-workflow-negative-cases.mjs";
12
-
13
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
14
- const validator = path.join(root, "scripts", "validate-governance.mjs");
15
- const adapterHarness = path.join(root, "scripts", "test-reference-adapters.mjs");
16
- const adapterPipeParser = 'let output = ""; process.stdin.setEncoding("utf8"); process.stdin.on("data", (chunk) => { output += chunk; }); process.stdin.on("end", () => { const report = JSON.parse(output); const complete = report.ok === true && report.failures.length === 0 && report.results.length === 42; process.stdout.write(complete ? "42\\n" : "incomplete\\n"); process.exitCode = complete ? 0 : 1; });';
17
-
18
- const cases = [
19
- { name: "missing_governance", omit: ["GOVERNANCE.md"], expect: "GOVERNANCE.md: missing file" },
20
- { name: "broad_profile_sources_claim_no_generated_artifacts", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace(/`design-engineering\/reference-profiles\/governed-local\/editorial\/profile\.json`[^|]+/, "`design-engineering/reference-profiles/governed-local/**`") }, expect: "GOVERNANCE.md: governed local reference profile sources must be the six explicit canonical profile files" },
21
- { name: "missing_matrix_stale_trigger", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace("Generated structure changes, generated-warning changes, or generated metadata changes.", "Generated structure changes.") }, expect: "GOVERNANCE.md: missing Generated structure changes, generated-warning changes, or generated metadata changes." },
22
- { name: "missing_game_ui_domain_family", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace(/^\| Game UI domain guidance .*\n/m, "") }, expect: "GOVERNANCE.md: missing Game UI domain guidance" },
23
- { name: "missing_evidence_fixture_coverage", mutate: { "quality/evidence/executable-evidence.md": "Missing governance file or generated warning fixtures must fail." }, expect: "quality/evidence/executable-evidence.md: missing Missing governance file, generated warning, generated metadata, CODEOWNERS coverage, or stale policy fixtures must fail." },
24
- {
25
- name: "missing_generated_warning",
26
- mutate: {
27
- "patterns/stacking/stack.md": [
28
- "---",
29
- "lifecycle: generated",
30
- "generated_from: scripts/generate-patterns.mjs, scripts/pattern-data.mjs",
31
- "---",
32
- "",
33
- "# stack",
34
- "",
35
- ].join("\n"),
36
- },
37
- expect: "patterns/stacking/stack.md: missing generated warning",
38
- },
39
- { name: "missing_generated_metadata", mutate: { "patterns/stacking/stack.md": `# stack\n\n${generatedWarning}\n` }, expect: "patterns/stacking/stack.md: missing lifecycle: generated" },
40
- {
41
- name: "missing_codeowners_coverage",
42
- mutate: {
43
- ".github/CODEOWNERS": [
44
- "* @changeroa",
45
- "/GOVERNANCE.md @changeroa",
46
- "/scripts/pattern-data.mjs @changeroa",
47
- "/patterns/ @changeroa",
48
- "",
49
- ].join("\n"),
50
- },
51
- expect: ".github/CODEOWNERS: missing /README.md @changeroa",
52
- },
53
- {
54
- name: "missing_workflow_permissions",
55
- mutate: {
56
- ".github/workflows/validate.yml": [
57
- "node -c scripts/validate-governance.mjs",
58
- "node -c scripts/test-validate-governance.mjs",
59
- "node scripts/validate-governance.mjs --json",
60
- "node scripts/test-validate-governance.mjs --json",
61
- "",
62
- ].join("\n"),
63
- },
64
- expect: ".github/workflows/validate.yml: missing permissions:",
65
- },
66
- { name: "missing_stale_policy", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace("scheduled_stale_audit: deferred\n", "") }, expect: "GOVERNANCE.md: missing scheduled_stale_audit: deferred" },
67
- { name: "missing_evidence_audit_policy", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace("scheduled_evidence_audit: active_advisory\n", "") }, expect: "GOVERNANCE.md: missing scheduled_evidence_audit: active_advisory" },
68
- {
69
- name: "paraphrased_stale_policy",
70
- mutate: {
71
- "GOVERNANCE.md": files["GOVERNANCE.md"].replace(
72
- "Decision: run a weekly advisory audit only for evidence records that already declare `expires_at` or `review_by`.",
73
- "Decision: inspect old evidence from time to time.",
74
- ),
75
- },
76
- expect: "GOVERNANCE.md: missing Decision: run a weekly advisory audit only for evidence records that already declare `expires_at` or `review_by`.",
77
- },
78
- { name: "missing_no_universal_age_boundary", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace("No repository-wide maximum age or inferred time-to-live applies.", "Evidence gets old after 30 days.") }, expect: "GOVERNANCE.md: missing No repository-wide maximum age or inferred time-to-live applies." },
79
- { name: "missing_freshness_workflow", omit: [".github/workflows/evidence-freshness.yml"], expect: ".github/workflows/evidence-freshness.yml: missing file" },
80
- { name: "freshness_schedule_drift", mutate: { ".github/workflows/evidence-freshness.yml": files[".github/workflows/evidence-freshness.yml"].replace("cron: '0 5 * * 1'", "cron: '0 5 * * 2'") }, expect: ".github/workflows/evidence-freshness.yml: missing Monday 05:00 UTC schedule" },
81
- { name: "freshness_mode_became_blocking", mutate: { ".github/workflows/evidence-freshness.yml": files[".github/workflows/evidence-freshness.yml"].replace("--mode advisory", "--mode blocking") }, expect: ".github/workflows/evidence-freshness.yml: missing --mode advisory" },
82
- { name: "freshness_blanket_continue", mutate: { ".github/workflows/evidence-freshness.yml": `${files[".github/workflows/evidence-freshness.yml"]}\ncontinue-on-error: true\n` }, expect: ".github/workflows/evidence-freshness.yml: continue-on-error is forbidden because malformed records and tool failures must block" },
83
- { name: "consumer_browser_became_nonblocking", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" consumer-conformance:\n", " consumer-conformance:\n continue-on-error: true\n") }, expect: ".github/workflows/validate.yml: consumer-conformance must be blocking" },
84
- {
85
- name: "consumer_browser_command_commented_out",
86
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: |\n # npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line\n true") },
87
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
88
- },
89
- {
90
- name: "consumer_browser_command_relocated",
91
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: true").replace(" chromium-sentinel:\n", " chromium-sentinel:\n steps:\n - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line\n") },
92
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
93
- },
94
- {
95
- name: "consumer_browser_command_hidden_in_env",
96
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - name: Hidden browser command\n env:\n run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line\n run: true") },
97
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
98
- },
99
- {
100
- name: "consumer_browser_command_hidden_in_inline_comment",
101
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: true # npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
102
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
103
- },
104
- {
105
- name: "consumer_browser_command_in_disabled_step",
106
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - name: Disabled browser command\n if: false\n run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
107
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
108
- },
109
- {
110
- name: "consumer_browser_command_hidden_in_heredoc",
111
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: |\n cat <<'PROBE'\n npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line\n PROBE\n true") },
112
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
113
- },
114
- {
115
- name: "consumer_browser_command_hidden_in_numeric_heredoc",
116
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: |\n cat <<'123'\n npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line\n 123\n true") },
117
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
118
- },
119
- {
120
- name: "consumer_browser_command_echo_only",
121
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: echo npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
122
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
123
- },
124
- {
125
- name: "consumer_browser_command_shell_builtin_echo",
126
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: command echo npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
127
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
128
- },
129
- {
130
- name: "consumer_browser_command_short_circuited",
131
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: false && npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
132
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
133
- },
134
- {
135
- name: "consumer_browser_command_failure_ignored",
136
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line || true") },
137
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
138
- },
139
- {
140
- name: "consumer_browser_command_split_failure_ignored",
141
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: |\n npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line \\\n || true") },
142
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
143
- },
144
- {
145
- name: "consumer_browser_command_folded_failure_ignored",
146
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - run: >-\n npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line\n || true") },
147
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
148
- },
149
- {
150
- name: "consumer_browser_command_compound_false_step",
151
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - if: ${{ false && true }}\n run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
152
- expect: ".github/workflows/validate.yml: consumer-conformance: required command steps must be unconditional",
153
- },
154
- {
155
- name: "consumer_browser_job_compound_false",
156
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" consumer-conformance:\n", " consumer-conformance:\n if: ${{ false && true }}\n") },
157
- expect: ".github/workflows/validate.yml: consumer-conformance job must be unconditional",
158
- },
159
- {
160
- name: "consumer_browser_command_quoted_disabled_step",
161
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line", " - name: Disabled browser command\n \"if\": false # disabled\n run: npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line") },
162
- expect: ".github/workflows/validate.yml: consumer-conformance: missing npx playwright test tests/consumer-conformance.spec.mjs --project=chromium --reporter=line",
163
- },
164
- {
165
- name: "consumer_browser_job_disabled",
166
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" consumer-conformance:\n", " consumer-conformance:\n if: false\n") },
167
- expect: ".github/workflows/validate.yml: consumer-conformance job must be enabled",
168
- },
169
- {
170
- name: "page_lifecycle_command_commented_out",
171
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" - run: node scripts/finalize-page-evidence.mjs --json", " - run: |\n # node scripts/finalize-page-evidence.mjs --json\n true") },
172
- expect: ".github/workflows/validate.yml: consumer-page-evidence: missing node scripts/finalize-page-evidence.mjs",
173
- },
174
- { name: "page_capture_became_blocking", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(" continue-on-error: true\n env:\n CONSUMER_CONFORMANCE_CAPTURE_DIR", " env:\n CONSUMER_CONFORMANCE_CAPTURE_DIR") }, expect: ".github/workflows/validate.yml: consumer-page-evidence must be nonblocking" },
175
- { name: "paraphrased_governance_link_label", mutate: { "README.md": files["README.md"].replace("[Governance, Lifecycle, And Docs-As-Code]", "[Governance reference]") }, expectWarning: "README.md: recommended link label missing [Governance, Lifecycle, And Docs-As-Code](GOVERNANCE.md)" },
176
- { name: "missing_motion_codeowner", mutate: { ".github/CODEOWNERS": files[".github/CODEOWNERS"].replace("/motion/ @changeroa\n", "") }, expect: ".github/CODEOWNERS: missing /motion/ @changeroa" },
177
- { name: "missing_game_ui_codeowner", mutate: { ".github/CODEOWNERS": files[".github/CODEOWNERS"].replace("/game-ui/ @changeroa\n", "") }, expect: ".github/CODEOWNERS: missing /game-ui/ @changeroa" },
178
- { name: "missing_consumer_reference_codeowner", mutate: { ".github/CODEOWNERS": files[".github/CODEOWNERS"].replace("/consumer-reference/ @changeroa\n", "") }, expect: ".github/CODEOWNERS: missing /consumer-reference/ @changeroa" },
179
- { name: "missing_baseline_codeowner", mutate: { ".github/CODEOWNERS": files[".github/CODEOWNERS"].replace("/consumer-reference/baselines/ @changeroa\n", "") }, expect: ".github/CODEOWNERS: missing /consumer-reference/baselines/ @changeroa" },
180
- { name: "missing_promotion_codeowner", mutate: { ".github/CODEOWNERS": files[".github/CODEOWNERS"].replace("/consumer-reference/policies/ @changeroa\n", "") }, expect: ".github/CODEOWNERS: missing /consumer-reference/policies/ @changeroa" },
181
- { name: "missing_promotion_ci_wiring", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("node scripts/test-validate-promotion-rfc.mjs --json\n", "") }, expect: ".github/workflows/validate.yml: missing node scripts/test-validate-promotion-rfc.mjs --json" },
182
- { name: "missing_stable_count_boundary", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace("Shared stable has no numeric adoption threshold.", "Stable uses an adoption threshold.") }, expect: "GOVERNANCE.md: missing Shared stable has no numeric adoption threshold" },
183
- { name: "fake_promotion_policy_claim", mutate: { "consumer-reference/policies/shared-experimental.json": files["consumer-reference/policies/shared-experimental.json"].replace('"promotion_occurred": false', '"promotion_occurred": true') }, expect: 'consumer-reference/policies/shared-experimental.json: missing "promotion_occurred": false' },
184
- { name: "missing_domain_family", mutate: { "GOVERNANCE.md": files["GOVERNANCE.md"].replace("| Motion domain guidance |", "| Motion reference notes |") }, expect: "GOVERNANCE.md: missing Motion domain guidance" },
185
- { name: "missing_domain_ci_wiring", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("node scripts/validate-domains.mjs --json\n", "") }, expect: ".github/workflows/validate.yml: missing node scripts/validate-domains.mjs --json" },
186
- { name: "missing_domain_evidence_coverage", mutate: { "quality/evidence/executable-evidence.md": files["quality/evidence/executable-evidence.md"].replace("Domain metadata, immutable provenance, scope boundaries, and root-route fixtures must fail.", "Domain fixtures must fail.") }, expect: "quality/evidence/executable-evidence.md: missing Domain metadata, immutable provenance, scope boundaries, and root-route fixtures must fail." },
187
- { name: "missing_sentinel_ci_wiring", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replaceAll("node scripts/test-consumer-reference-sentinel.mjs", "") }, expect: ".github/workflows/validate.yml: missing node scripts/test-consumer-reference-sentinel.mjs" },
188
- { name: "missing_component_source_contract_ci", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("node scripts/test-component-state-source-contract.mjs", "") }, expect: ".github/workflows/validate.yml: missing node scripts/test-component-state-source-contract.mjs" },
189
- { name: "missing_visual_schema_ci", mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("consumer-reference/schema/visual-evidence.schema.json", "") }, expect: ".github/workflows/validate.yml: missing consumer-reference/schema/visual-evidence.schema.json" },
190
- ...componentStateWorkflowCases(files[".github/workflows/validate.yml"]),
191
- { name: "missing_sentinel_evidence_coverage", mutate: { "quality/evidence/executable-evidence.md": files["quality/evidence/executable-evidence.md"].replace("The proposed Chromium sentinel preserves canonical card-grid geometry and truth-derived calibration evidence.", "Chromium evidence exists.") }, expect: "quality/evidence/executable-evidence.md: missing The proposed Chromium sentinel preserves canonical card-grid geometry and truth-derived calibration evidence." },
192
- { name: "missing_component_state_evidence_coverage", mutate: { "quality/evidence/executable-evidence.md": files["quality/evidence/executable-evidence.md"].replace("Governed-local button states retain source-bound visual, DOM, and accessibility-tree evidence across both example profiles.", "Component evidence exists.") }, expect: "quality/evidence/executable-evidence.md: missing Governed-local button states retain source-bound visual, DOM, and accessibility-tree evidence across both example profiles." },
193
- {
194
- name: "missing_scoped_checkout_sha_trust",
195
- mutate: {
196
- ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(
197
- "checkout_sha=\"$(git -c safe.directory=\"$GITHUB_WORKSPACE\" rev-parse HEAD)\"",
198
- "checkout_sha=\"$(git rev-parse HEAD)\"",
199
- ),
200
- },
201
- expect: ".github/workflows/validate.yml: missing checkout_sha=\"$(git -c safe.directory=\"$GITHUB_WORKSPACE\" rev-parse HEAD)\"",
202
- },
203
- {
204
- name: "reject_broad_checkout_sha_trust",
205
- mutate: {
206
- ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace(
207
- "checkout_sha=\"$(git -c safe.directory=\"$GITHUB_WORKSPACE\" rev-parse HEAD)\"",
208
- "checkout_sha=\"$(git -c safe.directory='*' rev-parse HEAD)\"",
209
- ),
210
- },
211
- expect: ".github/workflows/validate.yml: broad Git safe.directory wildcard is forbidden",
212
- },
213
- {
214
- name: "missing_canonical_repository_wiring",
215
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("--repository \"changeroa/StyleGallery\" \\", "--repository \"$GITHUB_REPOSITORY\" \\") },
216
- expect: ".github/workflows/validate.yml: missing --repository \"changeroa/StyleGallery\" \\",
217
- },
218
- {
219
- name: "missing_execution_repository_wiring",
220
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("--execution-repository \"$GITHUB_REPOSITORY\" \\\n", "") },
221
- expect: ".github/workflows/validate.yml: missing --execution-repository \"$GITHUB_REPOSITORY\" \\",
222
- },
223
- {
224
- name: "workflow_metadata_repository_mismatch",
225
- mutate: { ".github/workflows/validate.yml": files[".github/workflows/validate.yml"].replace("\"changeroa/StyleGallery\" \"$GITHUB_REPOSITORY\" \"$GITHUB_RUN_ID\"", "\"$GITHUB_REPOSITORY\" \"changeroa/StyleGallery\" \"$GITHUB_RUN_ID\"") },
226
- expect: ".github/workflows/validate.yml: missing \"changeroa/StyleGallery\" \"$GITHUB_REPOSITORY\" \"$GITHUB_RUN_ID\"",
227
- },
228
- ...governanceMatrixCases(files["GOVERNANCE.md"]),
229
- ...workflowSafetyCases(files[".github/workflows/validate.yml"]),
230
- { name: "success_path", expect: null },
231
- ];
232
-
233
- for (const [pathIndex, relative] of ["consumer-reference/contract.md", "quality/evidence/executable-evidence.md", "GOVERNANCE.md"].entries()) {
234
- for (const [clauseIndex, clause] of sentinelProvenanceClauses.entries()) {
235
- cases.splice(cases.length - 1, 0,
236
- { name: `provenance_clause_deleted_${pathIndex}_${clauseIndex}`, mutate: { [relative]: files[relative].replace(clause, "") }, expect: `${relative}: missing ${clause}` },
237
- { name: `provenance_clause_misworded_${pathIndex}_${clauseIndex}`, mutate: { [relative]: files[relative].replace(clause, `Misworded ${clause.slice(1)}`) }, expect: `${relative}: missing ${clause}` },
238
- );
239
- }
240
- }
241
-
242
- function writeFixture(testCase) {
243
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), `layout-gallery-governance-${testCase.name}-`));
244
- const omitted = new Set(testCase.omit ?? []);
245
- const entries = { ...files, ...(testCase.mutate ?? {}) };
246
- for (const [relative, content] of Object.entries(entries)) {
247
- if (omitted.has(relative)) continue;
248
- const target = path.join(dir, relative);
249
- fs.mkdirSync(path.dirname(target), { recursive: true });
250
- fs.writeFileSync(target, content);
251
- }
252
- return dir;
253
- }
254
-
255
- function runCase(testCase) {
256
- const dir = writeFixture(testCase);
257
- const result = spawnSync(process.execPath, [validator, "--json"], {
258
- cwd: dir,
259
- encoding: "utf8",
260
- });
261
- fs.rmSync(dir, { force: true, recursive: true });
262
- const output = JSON.parse(result.stdout);
263
- const passed = testCase.expectWarning
264
- ? output.ok && output.warnings?.includes(testCase.expectWarning)
265
- : testCase.expect
266
- ? !output.ok && output.failures.includes(testCase.expect)
267
- : output.ok;
268
- return {
269
- actual: output,
270
- expected: testCase.expectWarning ?? testCase.expect ?? "ok:true",
271
- name: testCase.name,
272
- ok: passed,
273
- };
274
- }
275
-
276
- const results = cases.map(runCase);
277
- const adapterPipeCheck = spawnSync("sh", ["-c", '"$NODE_BIN" "$ADAPTER_HARNESS" --json | "$NODE_BIN" -e "$ADAPTER_PIPE_PARSER"'], {
278
- cwd: root, encoding: "utf8", env: { ...process.env, ADAPTER_HARNESS: adapterHarness, ADAPTER_PIPE_PARSER: adapterPipeParser, NODE_BIN: process.execPath },
279
- });
280
- results.push({
281
- actual: { status: adapterPipeCheck.status, stdout: adapterPipeCheck.stdout.trim() },
282
- expected: "complete 42-result JSON report through a pipe",
283
- name: "adapter_json_pipe_complete",
284
- ok: adapterPipeCheck.status === 0 && adapterPipeCheck.stdout.trim() === "42",
285
- });
286
- const report = {
287
- ok: results.every((result) => result.ok),
288
- results,
289
- };
290
-
291
- console.log(JSON.stringify(report, null, 2));
292
- process.exitCode = report.ok ? 0 : 1;
@@ -1,262 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
- import { spawnSync } from "node:child_process";
7
- import { fileURLToPath } from "node:url";
8
-
9
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
10
- const validator = path.join(root, "scripts", "validate-ia.mjs");
11
- const governedProfileRoutes = [
12
- ["Editorial profile", "editorial/profile.json"],
13
- ["Editorial state matrix", "editorial/generated/state-matrix.md"],
14
- ["Editorial keyboard matrix", "editorial/generated/keyboard-matrix.md"],
15
- ["Editorial evidence coverage", "editorial/generated/evidence-coverage.md"],
16
- ["Terminal profile", "terminal/profile.json"],
17
- ["Terminal state matrix", "terminal/generated/state-matrix.md"],
18
- ["Terminal keyboard matrix", "terminal/generated/keyboard-matrix.md"],
19
- ["Terminal evidence coverage", "terminal/generated/evidence-coverage.md"],
20
- ];
21
-
22
- const baseFiles = {
23
- "README.md": [
24
- "# layout-gallery",
25
- "",
26
- "Primary role: repository guide.",
27
- "",
28
- "## Repository Entry Roles",
29
- "",
30
- "| Entry | Primary role |",
31
- "| --- | --- |",
32
- "| [README](README.md) | Repository guide |",
33
- "| [Layout](layout/index.md) | Layout domain |",
34
- "| [Motion](motion/index.md) | Motion domain |",
35
- "| [Design Engineering](design-engineering/index.md) | Design Engineering domain |",
36
- "| [Platform Guides](platform-guides/index.md) | Platform Guides domain |",
37
- "| [Consumer Reference](consumer-reference/index.md) | Shared infrastructure contract |",
38
- "| [Consumer Migration Readiness](design-engineering/consumer-migration-readiness.md) | Migration method |",
39
- "",
40
- "## Task Routes",
41
- "",
42
- "| Task | Primary route |",
43
- "| --- | --- |",
44
- "| `plan a layout` | [Guide](GUIDE.md) |",
45
- "| `make a homepage` | [Homepage](recipes/homepage.md) |",
46
- "| `choose a primitive` | [Catalog](CATALOG.md) |",
47
- "| `review quality` | [Quality](quality/index.md) |",
48
- "| `check links` | [Quality](quality/index.md) |",
49
- "| `write a recipe` | [Recipes](recipes/index.md) |",
50
- "| `inspect pattern categories` | [Patterns](patterns/index.md) |",
51
- "| `fill a brief` | [Brief](guides/layout-brief.md) |",
52
- "| `record evidence` | [Evidence](quality/evidence/index.md) |",
53
- "| `run findability QA` | [Findability](quality/index.md) |",
54
- "",
55
- "## Link Policy",
56
- "",
57
- "- Navigation links move a reader to the next decision point.",
58
- "- Citation links identify source lineage or evidence boundaries.",
59
- "- Dependency links identify generated, validation, or composition relationships.",
60
- "",
61
- ].join("\n"),
62
- "index.md": [
63
- "# Bundle",
64
- "",
65
- "Primary role: OKF bundle map.",
66
- "",
67
- "- [Layout](layout/index.md)",
68
- "- [Motion](motion/index.md)",
69
- "- [Design Engineering](design-engineering/index.md)",
70
- "- [Platform Guides](platform-guides/index.md)",
71
- "- [Consumer reference](consumer-reference/index.md)",
72
- "- [Consumer migration readiness](design-engineering/consumer-migration-readiness.md)",
73
- "",
74
- ].join("\n"),
75
- "GUIDE.md": "# Guide\n\nPrimary role: planning workflow.\n",
76
- "CATALOG.md": "# Catalog\n\nPrimary role: pattern lookup.\n",
77
- "patterns/index.md": "# Patterns\n",
78
- "patterns/stacking/index.md": "# Stacking\n",
79
- "patterns/stacking/stack.md": leaf("Stack", "index.md", "../../recipes/index.md"),
80
- "recipes/index.md": "# Recipes\n",
81
- "recipes/homepage.md": leaf("Homepage", "index.md", "../quality/index.md"),
82
- "quality/index.md": "# Quality\n\n- [Consumer migration evidence gate](gates/consumer-migration-evidence.md)\n\n## Tree-Test Findability QA\n",
83
- "quality/gates/index.md": "# Gates\n\n- [Consumer migration evidence gate](consumer-migration-evidence.md)\n",
84
- "quality/gates/layout.md": leaf("Layout", "index.md", "../evidence/index.md"),
85
- "quality/gates/consumer-migration-evidence.md": leaf("Consumer Migration Evidence Gate", "index.md", "../evidence/consumer-migration.md"),
86
- "quality/evidence/index.md": "# Evidence\n\n- [Consumer migration evidence](consumer-migration.md)\n",
87
- "quality/evidence/consumer-migration.md": leaf("Consumer Migration Evidence", "index.md", "../../design-engineering/consumer-migration-readiness.md"),
88
- "layout/index.md": "# Layout\n\n- [Catalog](../CATALOG.md)\n",
89
- "motion/index.md": "# Motion\n\n- [Review](review.md)\n",
90
- "motion/review.md": leaf("Motion review", "index.md", "../design-engineering/index.md"),
91
- "design-engineering/index.md": "# Design Engineering\n\n- [Craft](craft.md)\n- [Consumer Migration Readiness](consumer-migration-readiness.md)\n- [Reference Profiles](reference-profiles/index.md)\n",
92
- "design-engineering/craft.md": leaf("Craft", "index.md", "../platform-guides/index.md"),
93
- "design-engineering/consumer-migration-readiness.md": leaf("Consumer Migration Readiness", "index.md", "../quality/gates/consumer-migration-evidence.md"),
94
- "design-engineering/reference-profiles/index.md": "# Reference Profiles\n\n- [Governed Local Profiles](governed-local/index.md)\n- [External Adaptation](external-adaptation/index.md)\n\nParent: [Design Engineering](../index.md).\nNext: [Governed Local Profiles](governed-local/index.md).\n",
95
- "design-engineering/reference-profiles/governed-local/index.md": [
96
- "# Governed Local Profiles",
97
- "",
98
- ...governedProfileRoutes.map(([label, target]) => `- [${label}](${target})`),
99
- "",
100
- "Parent: [Reference Profiles](../index.md).",
101
- "Next: [External Adaptation](../external-adaptation/index.md).",
102
- "",
103
- ].join("\n"),
104
- "design-engineering/reference-profiles/external-adaptation/index.md": "# External Adaptation\n\nParent: [Reference Profiles](../index.md).\nNext: [Platform Guides](../../../platform-guides/index.md).\n",
105
- "platform-guides/index.md": "# Platform Guides\n\n- [Apple](apple.md)\n",
106
- "platform-guides/apple.md": leaf("Apple", "index.md", "../layout/index.md"),
107
- "consumer-reference/index.md": "# Consumer Reference\n\n- [Contract](contract.md)\n- [Consumer Migration Readiness](../design-engineering/consumer-migration-readiness.md)\n",
108
- "consumer-reference/contract.md": leaf("Consumer Reference Contract", "index.md", "../quality/index.md"),
109
- };
110
-
111
- const cases = [
112
- {
113
- name: "missing_leaf_parent",
114
- mutate: {
115
- "patterns/stacking/stack.md": "# Stack\n\nNext: [Recipes](../../recipes/index.md)\n",
116
- },
117
- expect: "patterns/stacking/stack.md: missing Parent navigation link",
118
- },
119
- {
120
- name: "missing_leaf_next",
121
- mutate: {
122
- "patterns/stacking/stack.md": "# Stack\n\nParent: [Stacking](index.md)\n",
123
- },
124
- expect: "patterns/stacking/stack.md: missing Next navigation link",
125
- },
126
- {
127
- name: "missing_task_routes",
128
- mutate: {
129
- "README.md": "# layout-gallery\n\nPrimary role: repository guide.\n\n## Repository Entry Roles\n",
130
- },
131
- expect: "README.md: missing ## Task Routes",
132
- },
133
- {
134
- name: "missing_link_policy",
135
- mutate: {
136
- "README.md": baseFiles["README.md"].replace(/\n## Link Policy\n[\s\S]*$/, "\n"),
137
- },
138
- expect: "README.md: missing ## Link Policy",
139
- },
140
- {
141
- name: "missing_motion_readme_route",
142
- mutate: {
143
- "README.md": baseFiles["README.md"].replace("| [Motion](motion/index.md) | Motion domain |\n", ""),
144
- },
145
- expect: "README.md: missing [Motion](motion/index.md)",
146
- },
147
- {
148
- name: "motion_readme_route_only_in_fence",
149
- mutate: {
150
- "README.md": baseFiles["README.md"].replace("| [Motion](motion/index.md) | Motion domain |\n", "```md\n[Motion](motion/index.md)\n```\n"),
151
- },
152
- expect: "README.md: missing [Motion](motion/index.md)",
153
- },
154
- {
155
- name: "missing_design_engineering_index_route",
156
- mutate: {
157
- "index.md": baseFiles["index.md"].replace("- [Design Engineering](design-engineering/index.md)\n", ""),
158
- },
159
- expect: "index.md: missing [Design Engineering](design-engineering/index.md)",
160
- },
161
- {
162
- name: "missing_reference_profile_route",
163
- mutate: {
164
- "design-engineering/index.md": "# Design Engineering\n\n- [Craft](craft.md)\n",
165
- },
166
- expect: "design-engineering/index.md: missing [Reference Profiles](reference-profiles/index.md)",
167
- },
168
- ...governedProfileRoutes.map(([label, target]) => ({
169
- name: `missing_governed_route_${target.replace(/[^a-z]+/g, "_").replace(/^_|_$/g, "")}`,
170
- mutate: {
171
- "design-engineering/reference-profiles/governed-local/index.md": baseFiles["design-engineering/reference-profiles/governed-local/index.md"].replace(`- [${label}](${target})\n`, ""),
172
- },
173
- expect: `design-engineering/reference-profiles/governed-local/index.md: missing [${label}](${target})`,
174
- })),
175
- {
176
- name: "missing_external_adaptation_parent",
177
- mutate: {
178
- "design-engineering/reference-profiles/external-adaptation/index.md": "# External Adaptation\n\nNext: [Platform Guides](../../../platform-guides/index.md).\n",
179
- },
180
- expect: "design-engineering/reference-profiles/external-adaptation/index.md: missing Parent navigation link",
181
- },
182
- {
183
- name: "missing_consumer_reference_route",
184
- mutate: {
185
- "index.md": baseFiles["index.md"].replace("- [Consumer reference](consumer-reference/index.md)\n", ""),
186
- },
187
- expect: "index.md: missing [Consumer reference](consumer-reference/index.md)",
188
- },
189
- {
190
- name: "missing_consumer_migration_root_route",
191
- mutate: {
192
- "README.md": baseFiles["README.md"].replace("| [Consumer Migration Readiness](design-engineering/consumer-migration-readiness.md) | Migration method |\n", ""),
193
- },
194
- expect: "README.md: missing [Consumer Migration Readiness](design-engineering/consumer-migration-readiness.md)",
195
- },
196
- {
197
- name: "missing_consumer_migration_gate_route",
198
- mutate: {
199
- "quality/index.md": "# Quality\n\n## Tree-Test Findability QA\n",
200
- },
201
- expect: "quality/index.md: missing [Consumer migration evidence gate](gates/consumer-migration-evidence.md)",
202
- },
203
- {
204
- name: "missing_domain_leaf_parent",
205
- mutate: {
206
- "motion/review.md": "# Motion review\n\nNext: [Next](../design-engineering/index.md)\n",
207
- },
208
- expect: "motion/review.md: missing Parent navigation link",
209
- },
210
- {
211
- name: "missing_domain_leaf_next",
212
- mutate: {
213
- "motion/review.md": "# Motion review\n\nParent: [Motion](index.md)\n",
214
- },
215
- expect: "motion/review.md: missing Next navigation link",
216
- },
217
- {
218
- name: "success_path",
219
- expect: null,
220
- },
221
- ];
222
-
223
- function leaf(title, parent, next) {
224
- return `# ${title}\n\n## IA Navigation\n\nParent: [Parent](${parent}).\nNext: [Next](${next}).\n`;
225
- }
226
-
227
- function writeFixture(testCase) {
228
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), `layout-gallery-ia-${testCase.name}-`));
229
- const entries = { ...baseFiles, ...(testCase.mutate ?? {}) };
230
- for (const [relative, content] of Object.entries(entries)) {
231
- const target = path.join(dir, relative);
232
- fs.mkdirSync(path.dirname(target), { recursive: true });
233
- fs.writeFileSync(target, content);
234
- }
235
- return dir;
236
- }
237
-
238
- function runCase(testCase) {
239
- const dir = writeFixture(testCase);
240
- const result = spawnSync(process.execPath, [validator, "--json"], {
241
- cwd: dir,
242
- encoding: "utf8",
243
- });
244
- fs.rmSync(dir, { force: true, recursive: true });
245
- const output = JSON.parse(result.stdout);
246
- const passed = testCase.expect ? !output.ok && output.failures.includes(testCase.expect) : output.ok;
247
- return {
248
- name: testCase.name,
249
- ok: passed,
250
- expected: testCase.expect ?? "ok:true",
251
- actual: output,
252
- };
253
- }
254
-
255
- const results = cases.map(runCase);
256
- const report = {
257
- ok: results.every((result) => result.ok),
258
- results,
259
- };
260
-
261
- console.log(JSON.stringify(report, null, 2));
262
- process.exitCode = report.ok ? 0 : 1;
@@ -1,73 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
- import { spawnSync } from "node:child_process";
7
- import { fileURLToPath } from "node:url";
8
-
9
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
10
- const validator = path.join(root, "scripts", "validate-okf.mjs");
11
-
12
- const cases = [
13
- {
14
- name: "missing_frontmatter",
15
- files: { "index.md": "# Bundle\n\n* [Bad](bad.md) - Bad\n", "log.md": "# Log\n\n## 2026-07-02\n* Init.\n", "bad.md": "# Bad\n" },
16
- expect: "missing OKF frontmatter",
17
- },
18
- {
19
- name: "missing_type",
20
- files: { "index.md": "# Bundle\n\n* [Bad](bad.md) - Bad\n", "log.md": "# Log\n\n## 2026-07-02\n* Init.\n", "bad.md": "---\ntitle: Bad\n---\n# Bad\n" },
21
- expect: "missing required OKF type",
22
- },
23
- {
24
- name: "index_frontmatter",
25
- files: { "index.md": "---\ntype: Index\n---\n# Bundle\n\n* [Good](good.md) - Good\n", "log.md": "# Log\n\n## 2026-07-02\n* Init.\n", "good.md": concept("Concept", "Good") },
26
- expect: "index.md must not contain concept frontmatter",
27
- },
28
- {
29
- name: "malformed_log_date",
30
- files: { "index.md": "# Bundle\n\n* [Good](good.md) - Good\n", "log.md": "# Log\n\n## July 2, 2026\n* Init.\n", "good.md": concept("Concept", "Good") },
31
- expect: "log.md date heading must be YYYY-MM-DD",
32
- },
33
- {
34
- name: "success_path",
35
- files: { "index.md": "---\nokf_version: \"0.1\"\n---\n# Bundle\n\n* [Good](good.md) - Good\n", "log.md": "# Log\n\n## 2026-07-02\n* Init.\n", "good.md": concept("Concept", "Good") },
36
- expect: null,
37
- },
38
- ];
39
-
40
- function concept(type, title) {
41
- return `---\ntype: ${type}\ntitle: ${title}\ndescription: Valid OKF concept.\n---\n# ${title}\n`;
42
- }
43
-
44
- function runCase(testCase) {
45
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), `layout-gallery-okf-${testCase.name}-`));
46
- for (const [relative, content] of Object.entries(testCase.files)) {
47
- const target = path.join(dir, relative);
48
- fs.mkdirSync(path.dirname(target), { recursive: true });
49
- fs.writeFileSync(target, content);
50
- }
51
- const result = spawnSync(process.execPath, [validator, "--json"], {
52
- cwd: dir,
53
- encoding: "utf8",
54
- });
55
- fs.rmSync(dir, { force: true, recursive: true });
56
- const output = JSON.parse(result.stdout);
57
- const passed = testCase.expect ? !output.ok && output.failures.some((failure) => failure.includes(testCase.expect)) : output.ok;
58
- return {
59
- name: testCase.name,
60
- ok: passed,
61
- expected: testCase.expect ?? "ok:true",
62
- actual: output,
63
- };
64
- }
65
-
66
- const results = cases.map(runCase);
67
- const report = {
68
- ok: results.every((result) => result.ok),
69
- results,
70
- };
71
-
72
- console.log(JSON.stringify(report, null, 2));
73
- process.exitCode = report.ok ? 0 : 1;