stylegallery 0.1.0 → 0.1.1

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 +23 -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 +51 -0
  14. package/package.json +181 -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,174 +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-vocabulary.mjs");
11
-
12
- const glossary = [
13
- "# Controlled Vocabulary",
14
- "",
15
- "## Canonical Terms",
16
- "",
17
- "- Canonical: `domain`",
18
- " - Concept: top-level knowledge ownership",
19
- "- Canonical: `category`",
20
- " - Concept: domain-local browse placement",
21
- "- Canonical: `pattern`",
22
- " - Concept: reusable spatial primitive",
23
- "- Canonical: `recipe`",
24
- " - Concept: screen composition",
25
- "- Canonical: `gate`",
26
- " - Concept: quality decision contract",
27
- "- Canonical: `claim`",
28
- " - Concept: review assertion",
29
- "- Canonical: `evidence family`",
30
- " - Concept: evidence class",
31
- "- Canonical: `scroll ownership`",
32
- " - Concept: scroll responsibility",
33
- "- Canonical: `harmony`",
34
- " - Concept: content layout fit",
35
- "- Canonical: `debt`",
36
- " - Concept: accepted unresolved risk",
37
- "- Canonical: `consumer reference`",
38
- " - Concept: optional consumer record handoff",
39
- "- Canonical: `maturity`",
40
- " - Concept: consumer reference lifecycle",
41
- "- Canonical: `artifact mode`",
42
- " - Concept: consumer reference storage role",
43
- "",
44
- "## Aliases",
45
- "",
46
- "- Alias: `primitive` -> `pattern`",
47
- "",
48
- "## Deprecated Terms",
49
- "",
50
- "- Deprecated: `component` -> `pattern`",
51
- " - Reason: In Layout, component implies visual or framework ownership.",
52
- "",
53
- "## Local-Only Terms",
54
- "",
55
- "- Local-only: `OKF`",
56
- "- Local-only: `consumer component`",
57
- "",
58
- "## Scannability Checklist",
59
- "",
60
- "- Use headings for decision boundaries.",
61
- "",
62
- "## Vale Proposal",
63
- "",
64
- "Prose linting should wait until the vocabulary is stable.",
65
- "",
66
- ].join("\n");
67
-
68
- const files = {
69
- "README.md": "# layout-gallery\n\n[Controlled vocabulary](guides/vocabulary.md)\n",
70
- "GUIDE.md": "# Guide\n\n[Controlled vocabulary](guides/vocabulary.md)\n",
71
- "index.md": "# Index\n\n[Controlled vocabulary](guides/vocabulary.md)\n",
72
- "quality/index.md": "# Quality\n\n[Controlled vocabulary](../guides/vocabulary.md)\n",
73
- "guides/vocabulary.md": glossary,
74
- };
75
-
76
- const cases = [
77
- {
78
- name: "missing_domain_term",
79
- mutate: {
80
- "guides/vocabulary.md": glossary.replace("- Canonical: `domain`\n - Concept: top-level knowledge ownership\n", ""),
81
- },
82
- expect: "guides/vocabulary.md: missing canonical term domain",
83
- },
84
- {
85
- name: "missing_category_term",
86
- mutate: {
87
- "guides/vocabulary.md": glossary.replace("- Canonical: `category`\n - Concept: domain-local browse placement\n", ""),
88
- },
89
- expect: "guides/vocabulary.md: missing canonical term category",
90
- },
91
- {
92
- name: "missing_required_term",
93
- mutate: {
94
- "guides/vocabulary.md": glossary.replace("- Canonical: `debt`\n - Concept: accepted unresolved risk\n", ""),
95
- },
96
- expect: "guides/vocabulary.md: missing canonical term debt",
97
- },
98
- {
99
- name: "missing_consumer_reference_term",
100
- mutate: {
101
- "guides/vocabulary.md": glossary.replace("- Canonical: `consumer reference`\n - Concept: optional consumer record handoff\n", ""),
102
- },
103
- expect: "guides/vocabulary.md: missing canonical term consumer reference",
104
- },
105
- {
106
- name: "duplicate_concept",
107
- mutate: {
108
- "guides/vocabulary.md": glossary.replace(
109
- "- Canonical: `pattern`\n - Concept: reusable spatial primitive",
110
- "- Canonical: `pattern`\n - Concept: reusable spatial primitive\n- Canonical: `layout primitive`\n - Concept: reusable spatial primitive",
111
- ),
112
- },
113
- expect: "guides/vocabulary.md: concept \"reusable spatial primitive\" has multiple canonical terms: pattern, layout primitive",
114
- },
115
- {
116
- name: "missing_vale_boundary",
117
- mutate: {
118
- "guides/vocabulary.md": glossary.replace("Prose linting should wait until the vocabulary is stable.", "Enable Vale immediately."),
119
- },
120
- expect: "guides/vocabulary.md: missing Prose linting should wait until the vocabulary is stable.",
121
- },
122
- {
123
- name: "paraphrased_navigation_label",
124
- mutate: {
125
- "README.md": files["README.md"].replace("[Controlled vocabulary]", "[Vocabulary guide]"),
126
- },
127
- expectWarning: "README.md: recommended link label missing [Controlled vocabulary](guides/vocabulary.md)",
128
- },
129
- {
130
- name: "success_path",
131
- expect: null,
132
- },
133
- ];
134
-
135
- function writeFixture(testCase) {
136
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), `layout-gallery-vocabulary-${testCase.name}-`));
137
- const entries = { ...files, ...(testCase.mutate ?? {}) };
138
- for (const [relative, content] of Object.entries(entries)) {
139
- const target = path.join(dir, relative);
140
- fs.mkdirSync(path.dirname(target), { recursive: true });
141
- fs.writeFileSync(target, content);
142
- }
143
- return dir;
144
- }
145
-
146
- function runCase(testCase) {
147
- const dir = writeFixture(testCase);
148
- const result = spawnSync(process.execPath, [validator, "--json"], {
149
- cwd: dir,
150
- encoding: "utf8",
151
- });
152
- fs.rmSync(dir, { force: true, recursive: true });
153
- const output = JSON.parse(result.stdout);
154
- const passed = testCase.expectWarning
155
- ? output.ok && output.warnings?.includes(testCase.expectWarning)
156
- : testCase.expect
157
- ? !output.ok && output.failures.includes(testCase.expect)
158
- : output.ok;
159
- return {
160
- name: testCase.name,
161
- ok: passed,
162
- expected: testCase.expectWarning ?? testCase.expect ?? "ok:true",
163
- actual: output,
164
- };
165
- }
166
-
167
- const results = cases.map(runCase);
168
- const report = {
169
- ok: results.every((result) => result.ok),
170
- results,
171
- };
172
-
173
- console.log(JSON.stringify(report, null, 2));
174
- process.exitCode = report.ok ? 0 : 1;
@@ -1,293 +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-webpage-workflow.mjs");
11
-
12
- const files = {
13
- "README.md": "# layout-gallery\n\n- [Webpage Generation Workflow](guides/webpage-generation-workflow.md)\n",
14
- "GUIDE.md": [
15
- "# Layout Planning Guide",
16
- "",
17
- "- [Webpage generation workflow](guides/webpage-generation-workflow.md)",
18
- "- content-to-layout match",
19
- "- harmony evaluation",
20
- "- GPT Image reference",
21
- "- implementation handoff",
22
- "",
23
- ].join("\n"),
24
- "guides/layout-brief.md": [
25
- "# Layout Brief Template",
26
- "",
27
- "## Webpage Generation Intake",
28
- "",
29
- "Content-to-layout match:",
30
- "Harmony evaluation:",
31
- "GPT Image reference:",
32
- "Required preconditions before prompt:",
33
- "Image review extract-vs-ignore:",
34
- "Implementation handoff:",
35
- "Consumer reference: not_applicable",
36
- "Consumer reference reason: This blank planning template has no consumer record.",
37
- "Accepted image debt:",
38
- "",
39
- "## Minimum Required Fields By Use Case",
40
- "",
41
- "Homepage:",
42
- "Dashboard:",
43
- "Article:",
44
- "Form:",
45
- "Command surface:",
46
- "",
47
- "## Rejected Alternatives",
48
- "",
49
- "Rejected pattern or recipe:",
50
- "Reason rejected:",
51
- "",
52
- ].join("\n"),
53
- "guides/decision-tree.md": [
54
- "# Layout Decision Tree",
55
- "",
56
- "Rejected alternatives:",
57
- "",
58
- ].join("\n"),
59
- "guides/webpage-generation-workflow.md": [
60
- "---",
61
- "type: Planning Guide",
62
- "---",
63
- "",
64
- "# Webpage Generation Workflow",
65
- "",
66
- "## Use Cases",
67
- "## Content-to-Layout Match",
68
- "## Harmony Evaluation",
69
- "## GPT Image Reference",
70
- "Required preconditions before prompt:",
71
- "Extract from image:",
72
- "Ignore from image:",
73
- "## Implementation Handoff",
74
- "Implementation debt:",
75
- "Final implementation proof:",
76
- "Consumer reference: not_applicable",
77
- "Consumer reference reason: This generic workflow has no consumer record.",
78
- "[Consumer Reference Receiver Contract](../consumer-reference/contract.md)",
79
- "## Workflow Route Examples",
80
- "",
81
- "### Homepage Route",
82
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> Scroll owner -> Constraints -> Harmony evaluation -> GPT Image reference -> Implementation handoff",
83
- "",
84
- "### Dashboard Route",
85
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> Scroll owner -> Constraints -> Harmony evaluation -> GPT Image reference -> Implementation handoff",
86
- "",
87
- "### Article Route",
88
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> Scroll owner -> Constraints -> Harmony evaluation -> GPT Image reference -> Implementation handoff",
89
- "",
90
- "### Form Route",
91
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> Scroll owner -> Constraints -> Harmony evaluation -> GPT Image reference -> Implementation handoff",
92
- "",
93
- "### Command Surface Route",
94
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> Scroll owner -> Constraints -> Harmony evaluation -> GPT Image reference -> Implementation handoff",
95
- "",
96
- ].join("\n"),
97
- "recipes/index.md": "# Layout Recipes\n\n- [Homepage](homepage.md)\n",
98
- "recipes/homepage.md": [
99
- "---",
100
- "type: Layout Recipe",
101
- "screen_type: Homepage",
102
- "---",
103
- "",
104
- "# Homepage",
105
- "",
106
- "## Recommended Pattern Stack",
107
- "## Content-To-Layout Matching",
108
- "## GPT Image Reference",
109
- "Required preconditions before prompt:",
110
- "Image review extract-vs-ignore:",
111
- "",
112
- ].join("\n"),
113
- "quality/gates/index.md": "# Gate Contracts\n\n- [Harmony evaluation gate](harmony-evaluation.md)\n",
114
- "quality/gates/harmony-evaluation.md": [
115
- "---",
116
- "type: Quality Gate",
117
- "---",
118
- "",
119
- "# Harmony Evaluation Gate",
120
- "",
121
- "## Required Contract",
122
- "",
123
- "Content-to-layout match:",
124
- "Overall harmony:",
125
- "GPT Image reference:",
126
- "Implementation handoff:",
127
- "Rejected alternatives:",
128
- "Do not generate a GPT Image reference before harmony evaluation approves the semantic order, section jobs, pattern stack, scroll owner, and constraints.",
129
- "Source order, accessibility, brand correctness, and usability cannot be inferred from the image.",
130
- "Final implementation proof:",
131
- "",
132
- ].join("\n"),
133
- "design-engineering/consumer-migration-readiness.md": [
134
- "---",
135
- "lifecycle: experimental",
136
- "provenance_kind: local",
137
- "---",
138
- "# Consumer Migration Readiness",
139
- "## Migration Dimension Contract",
140
- "`behavior_inventory`",
141
- "`route_parity`",
142
- "`field_parity`",
143
- "`action_parity`",
144
- "`state_transitions`",
145
- "`contract_precedence`",
146
- "`direct_mutation`",
147
- "`indirect_mutation`",
148
- "`persistence_round_trip`",
149
- "`reset_boundary`",
150
- "`exact_time_boundary`",
151
- "`defaults_tri_state_mapping`",
152
- "`atomic_batch_behavior`",
153
- "Consumer migration conformance: declared",
154
- "Passing this method does not prove complete accessibility, product correctness, usability, visual quality, independent adoption, cross-browser equivalence, or owner approval.",
155
- ].join("\n"),
156
- "consumer-reference/contract.md": [
157
- "### Migration-Only Extension",
158
- "This field is migration-only.",
159
- "Do not add it to generic blank handoffs",
160
- "Consumer migration conformance: declared",
161
- ].join("\n"),
162
- "quality/gates/consumer-migration-evidence.md": [
163
- "# Consumer Migration Evidence Gate",
164
- "## Required Contract",
165
- "## Blocking Conditions",
166
- "thirteen migration dimensions",
167
- "Decision: pass | block",
168
- ].join("\n"),
169
- };
170
-
171
- const cases = [
172
- {
173
- name: "missing_workflow_file",
174
- omit: ["guides/webpage-generation-workflow.md"],
175
- expect: "guides/webpage-generation-workflow.md: missing file",
176
- },
177
- {
178
- name: "missing_harmony_anchor",
179
- mutate: {
180
- "quality/gates/harmony-evaluation.md": files["quality/gates/harmony-evaluation.md"].replace("Overall harmony:", "Overall fit:"),
181
- },
182
- expect: "quality/gates/harmony-evaluation.md: missing Overall harmony:",
183
- },
184
- {
185
- name: "missing_route_examples",
186
- mutate: {
187
- "guides/webpage-generation-workflow.md": files["guides/webpage-generation-workflow.md"].replace("## Workflow Route Examples", "## Workflow Routes"),
188
- },
189
- expect: "guides/webpage-generation-workflow.md: missing ## Workflow Route Examples",
190
- },
191
- {
192
- name: "missing_image_proof_boundary",
193
- mutate: {
194
- "quality/gates/harmony-evaluation.md": files["quality/gates/harmony-evaluation.md"].replace(
195
- "Source order, accessibility, brand correctness, and usability cannot be inferred from the image.",
196
- "Generated image alone is enough for source order and access decisions.",
197
- ),
198
- },
199
- expect: "quality/gates/harmony-evaluation.md: missing Source order, accessibility, brand correctness, and usability cannot be inferred from the image.",
200
- },
201
- {
202
- name: "misordered_gpt_image_route",
203
- mutate: {
204
- "guides/webpage-generation-workflow.md": files["guides/webpage-generation-workflow.md"].replace(
205
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> Scroll owner -> Constraints -> Harmony evaluation -> GPT Image reference -> Implementation handoff",
206
- "Content blocks -> Section jobs -> Recipe -> Pattern stack -> GPT Image reference -> Harmony evaluation -> Scroll owner -> Constraints -> Implementation handoff",
207
- ),
208
- },
209
- expect: "guides/webpage-generation-workflow.md: route Homepage places GPT Image reference before Harmony evaluation",
210
- },
211
- {
212
- name: "missing_rejected_alternatives",
213
- mutate: {
214
- "guides/layout-brief.md": files["guides/layout-brief.md"].replace("## Rejected Alternatives", "## Alternatives"),
215
- },
216
- expect: "guides/layout-brief.md: missing ## Rejected Alternatives",
217
- },
218
- {
219
- name: "missing_consumer_reference_reason",
220
- mutate: {
221
- "guides/webpage-generation-workflow.md": files["guides/webpage-generation-workflow.md"].replace("Consumer reference reason: This generic workflow has no consumer record.", ""),
222
- },
223
- expect: "guides/webpage-generation-workflow.md: missing Consumer reference reason:",
224
- },
225
- {
226
- name: "missing_migration_dimension",
227
- mutate: {
228
- "design-engineering/consumer-migration-readiness.md": files["design-engineering/consumer-migration-readiness.md"].replace("`atomic_batch_behavior`", "`batch_behavior`"),
229
- },
230
- expect: "design-engineering/consumer-migration-readiness.md: missing `atomic_batch_behavior`",
231
- },
232
- {
233
- name: "migration_field_in_ordinary_handoff",
234
- mutate: {
235
- "guides/webpage-generation-workflow.md": `${files["guides/webpage-generation-workflow.md"]}\nConsumer migration conformance: declared\n`,
236
- },
237
- expect: "guides/webpage-generation-workflow.md: ordinary handoff must not declare consumer migration conformance",
238
- },
239
- {
240
- name: "paraphrased_navigation_label",
241
- mutate: {
242
- "README.md": files["README.md"].replace("[Webpage Generation Workflow]", "[Webpage planning workflow]"),
243
- },
244
- expectWarning: "README.md: recommended link label missing [Webpage Generation Workflow](guides/webpage-generation-workflow.md)",
245
- },
246
- {
247
- name: "success_path",
248
- expect: null,
249
- },
250
- ];
251
-
252
- function writeFixture(testCase) {
253
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), `layout-gallery-webpage-workflow-${testCase.name}-`));
254
- const omitted = new Set(testCase.omit ?? []);
255
- const entries = { ...files, ...(testCase.mutate ?? {}) };
256
- for (const [relative, content] of Object.entries(entries)) {
257
- if (omitted.has(relative)) continue;
258
- const target = path.join(dir, relative);
259
- fs.mkdirSync(path.dirname(target), { recursive: true });
260
- fs.writeFileSync(target, content);
261
- }
262
- return dir;
263
- }
264
-
265
- function runCase(testCase) {
266
- const dir = writeFixture(testCase);
267
- const result = spawnSync(process.execPath, [validator, "--json"], {
268
- cwd: dir,
269
- encoding: "utf8",
270
- });
271
- fs.rmSync(dir, { force: true, recursive: true });
272
- const output = JSON.parse(result.stdout);
273
- const passed = testCase.expectWarning
274
- ? output.ok && output.warnings?.includes(testCase.expectWarning)
275
- : testCase.expect
276
- ? !output.ok && output.failures.includes(testCase.expect)
277
- : output.ok;
278
- return {
279
- name: testCase.name,
280
- ok: passed,
281
- expected: testCase.expectWarning ?? testCase.expect ?? "ok:true",
282
- actual: output,
283
- };
284
- }
285
-
286
- const results = cases.map(runCase);
287
- const report = {
288
- ok: results.every((result) => result.ok),
289
- results,
290
- };
291
-
292
- console.log(JSON.stringify(report, null, 2));
293
- process.exitCode = report.ok ? 0 : 1;
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import Ajv2020 from "ajv/dist/2020.js";
6
- import { readJson, validateCalibration, validateManifest } from "./baseline-contract.mjs";
7
-
8
- const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
9
- const options = { calibration: "consumer-reference/baselines/calibration.json", json: false, manifest: "consumer-reference/baselines/manifest.json" };
10
- const failures = [];
11
- for (let index = 2; index < process.argv.length; index += 1) {
12
- const argument = process.argv[index];
13
- if (argument === "--json") options.json = true;
14
- else if (argument === "--manifest" || argument === "--calibration") {
15
- const value = process.argv[index + 1];
16
- if (!value) failures.push({ code: "argument_value_required", message: `${argument} requires a value`, path: "<cli>" });
17
- else {
18
- options[argument.slice(2)] = value;
19
- index += 1;
20
- }
21
- } else failures.push({ code: "argument_unknown", message: `unsupported argument ${argument}`, path: "<cli>" });
22
- }
23
-
24
- const manifestPath = path.resolve(repositoryRoot, options.manifest);
25
- const calibrationPath = path.resolve(repositoryRoot, options.calibration);
26
- const manifestSchemaPath = path.join(repositoryRoot, "consumer-reference/schema/baseline-manifest.schema.json");
27
- const calibrationSchemaPath = path.join(repositoryRoot, "consumer-reference/schema/calibration-record.schema.json");
28
- const manifest = readJson(manifestPath, failures);
29
- const calibration = readJson(calibrationPath, failures);
30
- const manifestSchema = readJson(manifestSchemaPath, failures);
31
- const calibrationSchema = readJson(calibrationSchemaPath, failures);
32
- const ajv = new Ajv2020({ allErrors: true, strict: false });
33
- for (const [kind, value, schema, file] of [["manifest", manifest, manifestSchema, manifestPath], ["calibration", calibration, calibrationSchema, calibrationPath]]) {
34
- if (value === undefined || schema === undefined) continue;
35
- const validate = ajv.compile(schema);
36
- if (!validate(value)) for (const error of validate.errors ?? []) failures.push({ code: `baseline_${kind}_schema_invalid`, message: `${error.instancePath || "/"} ${error.message}`, path: file });
37
- }
38
- if (manifest !== undefined) failures.push(...validateManifest(manifest, manifestPath, repositoryRoot));
39
- if (calibration !== undefined) failures.push(...validateCalibration(calibration, calibrationPath));
40
- const uniqueFailures = [...new Map(failures.map((failure) => [`${failure.code}:${failure.path}:${failure.message}`, failure])).values()];
41
- const result = { failures: uniqueFailures, ok: uniqueFailures.length === 0, warnings: [] };
42
- if (options.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
43
- else if (!result.ok) process.stderr.write(`${result.failures.map((failure) => `${failure.code}: ${failure.message}`).join("\n")}\n`);
44
- if (!result.ok) process.exitCode = 1;
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import path from "node:path";
5
- import { patterns } from "./pattern-data.mjs";
6
-
7
- const args = new Set(process.argv.slice(2));
8
- const json = args.has("--json");
9
- const root = process.cwd();
10
- const failures = [];
11
-
12
- function slugDir(category) {
13
- return category.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
14
- }
15
-
16
- function read(relative) {
17
- return fs.readFileSync(path.join(root, relative), "utf8");
18
- }
19
-
20
- function requireIncludes(relative, text) {
21
- if (!read(relative).includes(text)) failures.push(`${relative}: missing ${text}`);
22
- }
23
-
24
- const expectedFiles = new Set();
25
- const expectedCategories = new Set();
26
-
27
- for (const [slug, category, problem] of patterns) {
28
- const dir = slugDir(category);
29
- const file = `patterns/${dir}/${slug}.md`;
30
- expectedFiles.add(file);
31
- expectedCategories.add(category);
32
- if (!fs.existsSync(path.join(root, file))) failures.push(`missing pattern file: ${file}`);
33
- requireIncludes("CATALOG.md", `- [${slug}](${file}) - ${category}: ${problem}`);
34
- requireIncludes(`patterns/${dir}/index.md`, `- [${slug}](${slug}.md) - ${problem}`);
35
- }
36
-
37
- for (const category of expectedCategories) {
38
- const dir = slugDir(category);
39
- requireIncludes("patterns/index.md", `- [${category}](${dir}/index.md)`);
40
- }
41
-
42
- const actualFiles = fs.readdirSync(path.join(root, "patterns"), { recursive: true })
43
- .filter((entry) => typeof entry === "string" && entry.endsWith(".md") && !entry.endsWith("index.md"))
44
- .map((entry) => `patterns/${entry}`);
45
-
46
- for (const file of actualFiles) {
47
- if (!expectedFiles.has(file)) failures.push(`unexpected pattern file: ${file}`);
48
- }
49
-
50
- const result = {
51
- actualPatternCount: actualFiles.length,
52
- expectedPatternCount: expectedFiles.size,
53
- failures,
54
- ok: failures.length === 0,
55
- };
56
-
57
- if (json) {
58
- console.log(JSON.stringify(result, null, 2));
59
- } else if (result.ok) {
60
- console.log(`ok: ${actualFiles.length} cataloged patterns`);
61
- } else {
62
- console.error(result.failures.join("\n"));
63
- }
64
-
65
- process.exitCode = result.ok ? 0 : 1;