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,107 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import path from "node:path";
5
- import { markdownLinkDestinations, structuralMarkdown } from "./markdown-structure.mjs";
6
-
7
- const arguments_ = process.argv.slice(2);
8
- const json = arguments_.includes("--json");
9
- const rootIndex = arguments_.indexOf("--root");
10
- const root = rootIndex === -1 ? process.cwd() : path.resolve(arguments_[rootIndex + 1] ?? "");
11
- const failures = [];
12
- const documents = [
13
- "game-ui/unity/architecture.md",
14
- "game-ui/unity/cli-loop.md",
15
- "game-ui/unity/org-wiki.md",
16
- "game-ui/unity/repository-map.md",
17
- "game-ui/unity/ui-systems.md",
18
- ];
19
- const expectedRevisions = new Map([
20
- ["Unity-Technologies/BagelGame", "5d0348bfa013f3c76299dd582c90a7549f66abce"],
21
- ["Unity-Technologies/EntityComponentSystemSamples", "6786a741ee1f118ed14cecfa02beae8e926937b0"],
22
- ["Unity-Technologies/InputSystem", "8a57d62081cf3546b46444e17223e0121a3568b2"],
23
- ["Unity-Technologies/SimpleUIDemo", "c33907f1ffa0f8a30b46f958d3cf45e5da08b01c"],
24
- ["Unity-Technologies/UIElementsExamples", "e940d1c9dddfe99fd500c9f34f4801856ad37f18"],
25
- ["Unity-Technologies/UIElementsUniteCPH2019RuntimeDemo", "fa4f2c70cf2d6127ab624cc11a2742260ca6ff20"],
26
- ["Unity-Technologies/UIElementsUniteLATurretDemo", "1fce133fe3a3473d418066d8005c64340e9985d5"],
27
- ["Unity-Technologies/UIToolkitUnityRoyaleRuntimeDemo", "9b5006d2580101b4d08d59d03d7dadc697d75311"],
28
- ["Unity-Technologies/UnityCsReference", "79f16640303119112ca5caed4d71c607d0dff6fb"],
29
- ["Unity-Technologies/XR-Interaction-Toolkit-Examples", "881f7e197c7b0958621ebd1a05f249bbe254d36f"],
30
- ["Unity-Technologies/a11y-public-sample", "ec14cfcb8c10bafab83ea02cd17759d77b225fae"],
31
- ["Unity-Technologies/com.unity.uiwidgets", "0310984e947881eca6c2657f1a2fcaaa19329c22"],
32
- ["Unity-Technologies/uGUI", "9edb4420267b6652090ece4c28c38bd98746a68e"],
33
- ["Unity-Technologies/ui-toolkit-manual-code-examples", "7ed6e7af9fc8a8f83facea818f47928d2e03a30f"],
34
- ["Unity-Technologies/unity-industry-viewer-template", "5d50da18f68b14c4dc15bcf3d535878cc2254497"],
35
- ["annulusgames/UGUIAnimationSamples", "343c8110e5683be209cc01ccb4cb986175e61643"],
36
- ["hatayama/unity-cli-loop", "61a0fe6d7da0aa9d0bcbc6d95944dd069c483ff0"],
37
- ["tasharen/ngui", "9bbc56f11e0e25b89fd55b9b9bc67ddf1f182fe2"],
38
- ]);
39
-
40
- function read(relative) {
41
- const target = path.join(root, relative);
42
- if (!fs.existsSync(target)) {
43
- failures.push(`${relative}: missing file`);
44
- return "";
45
- }
46
- return fs.readFileSync(target, "utf8");
47
- }
48
-
49
- function frontmatterValue(content, key) {
50
- const frontmatter = content.match(/^---\n([\s\S]*?)\n---\n/)?.[1] ?? "";
51
- return frontmatter.match(new RegExp(`^${key}:\\s*(.+)$`, "m"))?.[1]?.trim() ?? "";
52
- }
53
-
54
- function validateReviewedOn(relative, content) {
55
- const value = frontmatterValue(content, "reviewed_on");
56
- const valid = /^\d{4}-\d{2}-\d{2}$/.test(value) && !Number.isNaN(Date.parse(`${value}T00:00:00Z`));
57
- if (!valid) failures.push(`${relative}: reviewed_on must be an ISO calendar date`);
58
- }
59
-
60
- function validatePinnedLinks(relative, content) {
61
- for (const destination of markdownLinkDestinations(content)) {
62
- const match = destination.match(/^https:\/\/github\.com\/([^/]+\/[^/]+)\/(?:blob|tree)\/([^/]+)(?:\/|$)/);
63
- if (!match) continue;
64
- const [, repository, revision] = match;
65
- if (!/^[0-9a-f]{40}$/.test(revision) || /^0{40}$/.test(revision)) {
66
- failures.push(`${relative}: GitHub body citation must use a non-zero 40-character revision: ${repository}`);
67
- continue;
68
- }
69
- const expected = expectedRevisions.get(repository);
70
- if (expected && revision !== expected) failures.push(`${relative}: unexpected pinned revision for ${repository}: ${revision}`);
71
- }
72
- }
73
-
74
- function requireIncludes(relative, content, expected, label) {
75
- if (!content.includes(expected)) failures.push(`${relative}: missing ${label}`);
76
- }
77
-
78
- for (const relative of documents) {
79
- const content = read(relative);
80
- if (!content) continue;
81
- const body = structuralMarkdown(content);
82
- validateReviewedOn(relative, content);
83
- validatePinnedLinks(relative, body);
84
- requireIncludes(relative, body, "## Source, License, And Attribution", "source attribution section");
85
- }
86
-
87
- const architecture = structuralMarkdown(read("game-ui/unity/architecture.md"));
88
- requireIncludes("game-ui/unity/architecture.md", architecture, "https://github.com/annulusgames/UGUIAnimationSamples/blob/343c8110e5683be209cc01ccb4cb986175e61643/LICENSE", "pinned sample license");
89
-
90
- const cliLoop = structuralMarkdown(read("game-ui/unity/cli-loop.md"));
91
- requireIncludes("game-ui/unity/cli-loop.md", cliLoop, "https://github.com/hatayama/unity-cli-loop/blob/61a0fe6d7da0aa9d0bcbc6d95944dd069c483ff0/README.md", "pinned adapted source");
92
- requireIncludes("game-ui/unity/cli-loop.md", cliLoop, "https://github.com/hatayama/unity-cli-loop/blob/61a0fe6d7da0aa9d0bcbc6d95944dd069c483ff0/LICENSE.md", "pinned source license");
93
-
94
- const uiSystems = structuralMarkdown(read("game-ui/unity/ui-systems.md"));
95
- for (const [repository, revision, license] of [
96
- ["Unity-Technologies/uGUI", "9edb4420267b6652090ece4c28c38bd98746a68e", "com.unity.ugui/LICENSE.md"],
97
- ["Unity-Technologies/UnityCsReference", "79f16640303119112ca5caed4d71c607d0dff6fb", "LICENSE.md"],
98
- ["tasharen/ngui", "9bbc56f11e0e25b89fd55b9b9bc67ddf1f182fe2", "License.txt"],
99
- ]) {
100
- requireIncludes("game-ui/unity/ui-systems.md", uiSystems, `https://github.com/${repository}/blob/${revision}/${license}`, `pinned license for ${repository}`);
101
- }
102
-
103
- const result = { ok: failures.length === 0, checkedDocuments: documents.length, failures: [...new Set(failures)] };
104
- if (json) console.log(JSON.stringify(result, null, 2));
105
- else if (result.ok) console.log(`ok: ${result.checkedDocuments} Unity source contracts`);
106
- else console.error(result.failures.join("\n"));
107
- process.exit(result.ok ? 0 : 1);
@@ -1,115 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import path from "node:path";
5
-
6
- const args = new Set(process.argv.slice(2));
7
- const json = args.has("--json");
8
- const root = process.cwd();
9
- const failures = [];
10
- const warnings = [];
11
-
12
- const glossaryFile = "guides/vocabulary.md";
13
- const requiredTerms = [
14
- "domain",
15
- "category",
16
- "pattern",
17
- "recipe",
18
- "gate",
19
- "claim",
20
- "evidence family",
21
- "scroll ownership",
22
- "harmony",
23
- "debt",
24
- "consumer reference",
25
- "maturity",
26
- "artifact mode",
27
- ];
28
-
29
- const requiredIncludes = {
30
- [glossaryFile]: [
31
- "## Canonical Terms",
32
- "## Aliases",
33
- "## Deprecated Terms",
34
- "## Local-Only Terms",
35
- "## Scannability Checklist",
36
- "## Vale Proposal",
37
- "Prose linting should wait until the vocabulary is stable.",
38
- "Local-only: `consumer component`",
39
- "In Layout, component implies visual or framework ownership",
40
- ],
41
- };
42
-
43
- const recommendedLinks = {
44
- "README.md": { target: "guides/vocabulary.md", preferred: "[Controlled vocabulary](guides/vocabulary.md)" },
45
- "GUIDE.md": { target: "guides/vocabulary.md", preferred: "[Controlled vocabulary](guides/vocabulary.md)" },
46
- "index.md": { target: "guides/vocabulary.md", preferred: "[Controlled vocabulary](guides/vocabulary.md)" },
47
- "quality/index.md": { target: "../guides/vocabulary.md", preferred: "[Controlled vocabulary](../guides/vocabulary.md)" },
48
- };
49
-
50
- function read(relative) {
51
- const target = path.join(root, relative);
52
- if (!fs.existsSync(target)) {
53
- failures.push(`${relative}: missing file`);
54
- return "";
55
- }
56
- return fs.readFileSync(target, "utf8");
57
- }
58
-
59
- for (const [relative, snippets] of Object.entries(requiredIncludes)) {
60
- const content = read(relative);
61
- for (const snippet of snippets) {
62
- if (!content.includes(snippet)) failures.push(`${relative}: missing ${snippet}`);
63
- }
64
- }
65
-
66
- for (const [relative, link] of Object.entries(recommendedLinks)) {
67
- const content = read(relative);
68
- if (!content.includes(`](${link.target})`)) failures.push(`${relative}: missing link target ${link.target}`);
69
- if (!content.includes(link.preferred)) warnings.push(`${relative}: recommended link label missing ${link.preferred}`);
70
- }
71
-
72
- const glossary = read(glossaryFile);
73
- const canonicalRecords = [...glossary.matchAll(/^- Canonical: `([^`]+)`\n - Concept: ([^\n]+)/gm)].map((match) => ({
74
- term: match[1].trim(),
75
- concept: match[2].trim().toLowerCase(),
76
- }));
77
- const canonicalTerms = canonicalRecords.map((record) => record.term);
78
-
79
- for (const term of requiredTerms) {
80
- if (!canonicalTerms.includes(term)) failures.push(`${glossaryFile}: missing canonical term ${term}`);
81
- }
82
-
83
- const termsSeen = new Set();
84
- for (const term of canonicalTerms) {
85
- if (termsSeen.has(term)) failures.push(`${glossaryFile}: duplicate canonical term ${term}`);
86
- termsSeen.add(term);
87
- }
88
-
89
- const conceptToTerm = new Map();
90
- for (const record of canonicalRecords) {
91
- const existing = conceptToTerm.get(record.concept);
92
- if (existing && existing !== record.term) {
93
- failures.push(`${glossaryFile}: concept "${record.concept}" has multiple canonical terms: ${existing}, ${record.term}`);
94
- }
95
- conceptToTerm.set(record.concept, record.term);
96
- }
97
-
98
- const result = {
99
- ok: failures.length === 0,
100
- checkedFiles: [...new Set([...Object.keys(requiredIncludes), ...Object.keys(recommendedLinks)])],
101
- requiredTerms,
102
- canonicalTerms,
103
- failures,
104
- warnings,
105
- };
106
-
107
- if (json) {
108
- console.log(JSON.stringify(result, null, 2));
109
- } else if (result.ok) {
110
- console.log(`ok: ${canonicalTerms.length} canonical vocabulary terms (${warnings.length} warnings)`);
111
- } else {
112
- console.error(failures.join("\n"));
113
- }
114
-
115
- process.exitCode = result.ok ? 0 : 1;
@@ -1,254 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import path from "node:path";
5
-
6
- const args = new Set(process.argv.slice(2));
7
- const json = args.has("--json");
8
- const root = process.cwd();
9
- const failures = [];
10
- const warnings = [];
11
- const contents = new Map();
12
-
13
- const requiredIncludes = {
14
- "guides/layout-brief.md": [
15
- "## Webpage Generation Intake",
16
- "Content-to-layout match:",
17
- "Harmony evaluation:",
18
- "GPT Image reference:",
19
- "Required preconditions before prompt:",
20
- "Image review extract-vs-ignore:",
21
- "Implementation handoff:",
22
- "Consumer reference: not_applicable",
23
- "Consumer reference reason:",
24
- "Accepted image debt:",
25
- "## Minimum Required Fields By Use Case",
26
- "Homepage:",
27
- "Dashboard:",
28
- "Article:",
29
- "Form:",
30
- "Command surface:",
31
- "## Rejected Alternatives",
32
- "Rejected pattern or recipe:",
33
- "Reason rejected:",
34
- ],
35
- "guides/decision-tree.md": [
36
- "Rejected alternatives:",
37
- ],
38
- "guides/webpage-generation-workflow.md": [
39
- "type: Planning Guide",
40
- "# Webpage Generation Workflow",
41
- "## Use Cases",
42
- "## Content-to-Layout Match",
43
- "## Harmony Evaluation",
44
- "## GPT Image Reference",
45
- "Required preconditions before prompt:",
46
- "Extract from image:",
47
- "Ignore from image:",
48
- "## Implementation Handoff",
49
- "Implementation debt:",
50
- "Final implementation proof:",
51
- "Consumer reference: not_applicable",
52
- "Consumer reference reason:",
53
- "[Consumer Reference Receiver Contract](../consumer-reference/contract.md)",
54
- "## Workflow Route Examples",
55
- "### Homepage Route",
56
- "### Dashboard Route",
57
- "### Article Route",
58
- "### Form Route",
59
- "### Command Surface Route",
60
- ],
61
- "recipes/homepage.md": [
62
- "type: Layout Recipe",
63
- "screen_type: Homepage",
64
- "## Recommended Pattern Stack",
65
- "## Content-To-Layout Matching",
66
- "## GPT Image Reference",
67
- "Required preconditions before prompt:",
68
- "Image review extract-vs-ignore:",
69
- ],
70
- "quality/gates/harmony-evaluation.md": [
71
- "type: Quality Gate",
72
- "## Required Contract",
73
- "Content-to-layout match:",
74
- "Overall harmony:",
75
- "GPT Image reference:",
76
- "Implementation handoff:",
77
- "Rejected alternatives:",
78
- "Do not generate a GPT Image reference before harmony evaluation approves the semantic order, section jobs, pattern stack, scroll owner, and constraints.",
79
- "Source order, accessibility, brand correctness, and usability cannot be inferred from the image.",
80
- "Final implementation proof:",
81
- ],
82
- "design-engineering/consumer-migration-readiness.md": [
83
- "lifecycle: experimental",
84
- "provenance_kind: local",
85
- "# Consumer Migration Readiness",
86
- "## Migration Dimension Contract",
87
- "`behavior_inventory`",
88
- "`route_parity`",
89
- "`field_parity`",
90
- "`action_parity`",
91
- "`state_transitions`",
92
- "`contract_precedence`",
93
- "`direct_mutation`",
94
- "`indirect_mutation`",
95
- "`persistence_round_trip`",
96
- "`reset_boundary`",
97
- "`exact_time_boundary`",
98
- "`defaults_tri_state_mapping`",
99
- "`atomic_batch_behavior`",
100
- "Consumer migration conformance: declared",
101
- "Passing this method does not prove complete accessibility, product correctness, usability, visual quality, independent adoption, cross-browser equivalence, or owner approval.",
102
- ],
103
- "consumer-reference/contract.md": [
104
- "### Migration-Only Extension",
105
- "This field is migration-only.",
106
- "Do not add it to generic blank handoffs",
107
- "Consumer migration conformance: declared",
108
- ],
109
- "quality/gates/consumer-migration-evidence.md": [
110
- "# Consumer Migration Evidence Gate",
111
- "## Required Contract",
112
- "## Blocking Conditions",
113
- "thirteen migration dimensions",
114
- "Decision: pass | block",
115
- ],
116
- };
117
-
118
- const requiredLinks = {
119
- "README.md": { target: "guides/webpage-generation-workflow.md", preferred: "[Webpage Generation Workflow](guides/webpage-generation-workflow.md)" },
120
- "GUIDE.md": { target: "guides/webpage-generation-workflow.md", preferred: "[Webpage generation workflow](guides/webpage-generation-workflow.md)" },
121
- "recipes/index.md": { target: "homepage.md", preferred: "[Homepage](homepage.md)" },
122
- "quality/gates/index.md": { target: "harmony-evaluation.md", preferred: "[Harmony evaluation gate](harmony-evaluation.md)" },
123
- };
124
-
125
- const recommendedIncludes = {
126
- "GUIDE.md": [
127
- "content-to-layout match",
128
- "harmony evaluation",
129
- "GPT Image reference",
130
- "implementation handoff",
131
- ],
132
- };
133
-
134
- const routeSteps = [
135
- "Content blocks",
136
- "Section jobs",
137
- "Recipe",
138
- "Pattern stack",
139
- "Scroll owner",
140
- "Constraints",
141
- "Harmony evaluation",
142
- "GPT Image reference",
143
- "Implementation handoff",
144
- ];
145
-
146
- const workflowRoutes = [
147
- "Homepage",
148
- "Dashboard",
149
- "Article",
150
- "Form",
151
- "Command Surface",
152
- ];
153
-
154
- function read(relative) {
155
- if (contents.has(relative)) return contents.get(relative);
156
- const absolute = path.join(root, relative);
157
- if (!fs.existsSync(absolute)) {
158
- failures.push(`${relative}: missing file`);
159
- contents.set(relative, "");
160
- return "";
161
- }
162
- const content = fs.readFileSync(absolute, "utf8");
163
- contents.set(relative, content);
164
- return content;
165
- }
166
-
167
- for (const [relative, snippets] of Object.entries(requiredIncludes)) {
168
- const content = read(relative);
169
- for (const snippet of snippets) {
170
- if (!content.includes(snippet)) failures.push(`${relative}: missing ${snippet}`);
171
- }
172
- }
173
-
174
- for (const [relative, link] of Object.entries(requiredLinks)) {
175
- const content = read(relative);
176
- if (!content.includes(`](${link.target})`)) failures.push(`${relative}: missing link target ${link.target}`);
177
- if (!content.includes(link.preferred)) warnings.push(`${relative}: recommended link label missing ${link.preferred}`);
178
- }
179
-
180
- for (const [relative, snippets] of Object.entries(recommendedIncludes)) {
181
- const content = read(relative);
182
- for (const snippet of snippets) {
183
- if (!content.includes(snippet)) warnings.push(`${relative}: recommended prose missing ${snippet}`);
184
- }
185
- }
186
-
187
- function routeSection(content, route) {
188
- const heading = `### ${route} Route`;
189
- const start = content.indexOf(heading);
190
- if (start === -1) return "";
191
- const afterHeading = content.slice(start + heading.length);
192
- const nextHeading = afterHeading.search(/\n### /);
193
- return nextHeading === -1 ? afterHeading : afterHeading.slice(0, nextHeading);
194
- }
195
-
196
- function requireRouteOrder(relative, route) {
197
- const content = read(relative);
198
- const section = routeSection(content, route);
199
- if (!section) {
200
- failures.push(`${relative}: missing ### ${route} Route`);
201
- return;
202
- }
203
-
204
- const harmonyIndex = section.indexOf("Harmony evaluation");
205
- const imageIndex = section.indexOf("GPT Image reference");
206
- if (harmonyIndex !== -1 && imageIndex !== -1 && imageIndex < harmonyIndex) {
207
- failures.push(`${relative}: route ${route} places GPT Image reference before Harmony evaluation`);
208
- }
209
-
210
- let previousIndex = -1;
211
- let previousStep = "";
212
- for (const step of routeSteps) {
213
- const index = section.indexOf(step);
214
- if (index === -1) {
215
- failures.push(`${relative}: route ${route} missing ${step}`);
216
- continue;
217
- }
218
- if (index < previousIndex) {
219
- failures.push(`${relative}: route ${route} places ${step} before ${previousStep}`);
220
- }
221
- previousIndex = index;
222
- previousStep = step;
223
- }
224
- }
225
-
226
- for (const route of workflowRoutes) {
227
- requireRouteOrder("guides/webpage-generation-workflow.md", route);
228
- }
229
-
230
- for (const relative of ["guides/layout-brief.md", "guides/webpage-generation-workflow.md", "quality/gates/harmony-evaluation.md"]) {
231
- if (/^Consumer migration conformance: declared$/m.test(read(relative))) {
232
- failures.push(`${relative}: ordinary handoff must not declare consumer migration conformance`);
233
- }
234
- }
235
-
236
- const result = {
237
- ok: failures.length === 0,
238
- checkedFiles: [...new Set([...Object.keys(requiredIncludes), ...Object.keys(requiredLinks), ...Object.keys(recommendedIncludes)])],
239
- checkedRequirements: Object.values(requiredIncludes).reduce((total, snippets) => total + snippets.length, 0)
240
- + Object.keys(requiredLinks).length
241
- + Object.values(recommendedIncludes).reduce((total, snippets) => total + snippets.length, 0),
242
- failures,
243
- warnings,
244
- };
245
-
246
- if (json) {
247
- console.log(JSON.stringify(result, null, 2));
248
- } else if (result.ok) {
249
- console.log(`ok: ${result.checkedRequirements} webpage workflow requirements (${warnings.length} warnings)`);
250
- } else {
251
- console.error(result.failures.join("\n"));
252
- }
253
-
254
- process.exitCode = result.ok ? 0 : 1;
@@ -1,20 +0,0 @@
1
- const environmentFields = Object.freeze([
2
- "browser",
3
- "browser_revision",
4
- "container_image",
5
- "platform",
6
- "playwright",
7
- "viewport",
8
- ]);
9
-
10
- function matchesEnvironment(approved, environment) {
11
- return environmentFields.every((field) => approved[field] === environment[field]);
12
- }
13
-
14
- export function visualExpectationFor(scenario, environment, approvedEnvironments) {
15
- const environments = approvedEnvironments.filter((approved) => matchesEnvironment(approved, environment));
16
- if (environments.length !== 1) throw new Error(`capture environment requires exactly one approved visual environment, found ${environments.length}`);
17
- const matches = scenario.expected.visual_image.filter((expectation) => expectation.environment_id === environments[0].id);
18
- if (matches.length !== 1) throw new Error(`scenario ${scenario.id} requires exactly one approved visual expectation for ${environments[0].id}, found ${matches.length}`);
19
- return matches[0];
20
- }
@@ -1,163 +0,0 @@
1
- function indentation(line) {
2
- return line.length - line.trimStart().length;
3
- }
4
-
5
- function mappingKeyIndentation(line) {
6
- const sequencePrefix = line.match(/^\s*-\s+/);
7
- return sequencePrefix ? sequencePrefix[0].length : indentation(line);
8
- }
9
-
10
- function mappingEntry(line) {
11
- const match = line.trim().replace(/^-\s+/, "").match(/^(?:([A-Za-z][A-Za-z0-9_-]*)|'([^']*)'|"([^"]*)")\s*:\s*(.*)$/);
12
- if (!match) return null;
13
- return { key: match[1] ?? match[2] ?? match[3], value: match[4] };
14
- }
15
-
16
- function isMappingHeader(entry, key) {
17
- return entry?.key === key && (entry.value === "" || entry.value.startsWith("#"));
18
- }
19
-
20
- function isBlockScalarHeader(value) {
21
- return /^[|>](?:[+-]?[1-9]|[1-9]?[+-])?(?:\s+#.*)?$/.test(value);
22
- }
23
-
24
- function structuralLines(lines) {
25
- let blockScalarIndentation = null;
26
- return lines.map((line) => {
27
- if (line.trim() === "" || line.trimStart().startsWith("#")) return line;
28
- const lineIndentation = indentation(line);
29
- if (blockScalarIndentation !== null && lineIndentation > blockScalarIndentation) return "";
30
- blockScalarIndentation = null;
31
- const entry = mappingEntry(line);
32
- if (entry && isBlockScalarHeader(entry.value)) blockScalarIndentation = lineIndentation;
33
- return line;
34
- });
35
- }
36
-
37
- function notationFailures(lines, relative) {
38
- let actionBlockScalar = false;
39
- let anchorsOrAliases = false;
40
- let directives = false;
41
- let documentMarkers = false;
42
- let escapedDoubleQuotedKey = false;
43
- let explicitMappingKey = false;
44
- let flowCollectionValue = false;
45
- let flowSequenceMapping = false;
46
- let mergeKey = false;
47
- let tags = false;
48
- for (const line of lines) {
49
- if (line.trim() === "" || line.trimStart().startsWith("#")) continue;
50
- const lineIndentation = indentation(line);
51
- const trimmed = line.trim();
52
- const structural = trimmed.replace(/^-\s+/, "");
53
- if (lineIndentation === 0 && /^%(?:YAML|TAG)\b/.test(trimmed)) directives = true;
54
- if (lineIndentation === 0 && /^(?:---|\.\.\.)(?:\s+#.*)?$/.test(trimmed)) documentMarkers = true;
55
- if (/^\?(?:\s|$)/.test(structural)) explicitMappingKey = true;
56
- if (/^!\S*(?:\s|$)/.test(structural)) tags = true;
57
- if (/^[&*][^\s:[\]{},]+(?:\s|:|$)/.test(structural)) anchorsOrAliases = true;
58
- if (/^<<\s*:/.test(structural)) mergeKey = true;
59
- const quotedKey = trimmed.match(/^(?:-\s+)?"((?:[^"\\]|\\.)*)"\s*:/)?.[1];
60
- if (quotedKey?.includes("\\")) escapedDoubleQuotedKey = true;
61
- if (/^-\s*\{/.test(trimmed)) flowSequenceMapping = true;
62
- const entry = mappingEntry(line);
63
- if (/^[\[{]/.test(entry?.value ?? "") || (!/^-\s*\{/.test(trimmed) && /^[\[{]/.test(structural))) flowCollectionValue = true;
64
- if (/^!\S*(?:\s|$)/.test(entry?.value ?? "")) tags = true;
65
- if (/^[&*][^\s[\]{},]+(?:\s|$)/.test(entry?.value ?? "")) anchorsOrAliases = true;
66
- if (entry?.key === "uses" && isBlockScalarHeader(entry.value)) actionBlockScalar = true;
67
- }
68
- const failures = [];
69
- if (directives) failures.push(`${relative}: YAML directives are forbidden`);
70
- if (documentMarkers) failures.push(`${relative}: YAML document markers are forbidden`);
71
- if (explicitMappingKey) failures.push(`${relative}: explicit mapping keys are forbidden`);
72
- if (tags) failures.push(`${relative}: YAML tags are forbidden`);
73
- if (anchorsOrAliases) failures.push(`${relative}: YAML anchors and aliases are forbidden`);
74
- if (mergeKey) failures.push(`${relative}: YAML merge keys are forbidden`);
75
- if (actionBlockScalar) failures.push(`${relative}: block scalar action refs are forbidden`);
76
- if (flowCollectionValue) failures.push(`${relative}: flow-style collection values are forbidden`);
77
- if (flowSequenceMapping) failures.push(`${relative}: flow-style sequence mappings are forbidden`);
78
- if (escapedDoubleQuotedKey) failures.push(`${relative}: escape sequences in double-quoted mapping keys are forbidden`);
79
- return failures;
80
- }
81
-
82
- function directMappingLines(lines, headerIndex, headerIndentation) {
83
- const nested = [];
84
- for (const line of lines.slice(headerIndex + 1)) {
85
- if (line.trim() === "" || line.trimStart().startsWith("#")) continue;
86
- const lineIndentation = indentation(line);
87
- if (lineIndentation <= headerIndentation) break;
88
- nested.push({ indentation: lineIndentation, trimmed: line.trim() });
89
- }
90
- if (nested.length === 0) return [];
91
- const directIndentation = Math.min(...nested.map((line) => line.indentation));
92
- return nested.filter((line) => line.indentation === directIndentation).map((line) => line.trimmed);
93
- }
94
-
95
- function actionRefFailures(lines, relative) {
96
- const failures = [];
97
- for (const line of lines) {
98
- const entry = mappingEntry(line);
99
- if (entry?.key !== "uses") continue;
100
- const reference = entry.value.match(/^([^\s#]+)/)?.[1];
101
- if (!reference) continue;
102
- if (reference.startsWith("./")) continue;
103
- if (reference.startsWith("docker://")) {
104
- failures.push(`${relative}: docker action refs are forbidden ${line.trim().replace(/^-\s*/, "")}`);
105
- continue;
106
- }
107
- if (!/^[^@\s]+@[a-f0-9]{40}$/i.test(reference)) failures.push(`${relative}: floating or unlabeled action ref ${line.trim().replace(/^-\s*/, "")}`);
108
- }
109
- return failures;
110
- }
111
-
112
- export function checkoutCredentialFailures(workflow, relative) {
113
- const failures = [];
114
- const lines = structuralLines(workflow.split("\n"));
115
- for (const [index, line] of lines.entries()) {
116
- const usesEntry = mappingEntry(line);
117
- if (usesEntry?.key !== "uses" || !/^actions\/checkout@/i.test(usesEntry.value)) continue;
118
- const usesIndentation = mappingKeyIndentation(line);
119
- const withHeaders = [];
120
- for (const [offset, following] of lines.slice(index + 1).entries()) {
121
- if (following.trim() === "" || following.trimStart().startsWith("#")) continue;
122
- const followingIndentation = indentation(following);
123
- if (followingIndentation < usesIndentation) break;
124
- if (followingIndentation === usesIndentation && isMappingHeader(mappingEntry(following), "with")) withHeaders.push(index + offset + 1);
125
- }
126
- const entries = withHeaders.length === 1 ? directMappingLines(lines, withHeaders[0], usesIndentation) : [];
127
- const credentialEntries = entries.map(mappingEntry).filter((entry) => entry?.key === "persist-credentials");
128
- const exactFalse = credentialEntries.length === 1 && /^false(?:\s+#.*)?$/.test(credentialEntries[0].value);
129
- if (!exactFalse) failures.push(`${relative}: every actions/checkout step must set persist-credentials: false`);
130
- }
131
- return failures;
132
- }
133
-
134
- function permissionFailures(lines, relative) {
135
- const failures = [];
136
- const headers = lines
137
- .map((line, index) => ({ entry: mappingEntry(line), index, indentation: indentation(line) }))
138
- .filter(({ entry }) => entry?.key === "permissions");
139
- if (headers.some((header) => header.indentation > 0)) failures.push(`${relative}: job-level permissions overrides are forbidden`);
140
- const topLevel = headers.filter((header) => header.indentation === 0);
141
- let exact = topLevel.length === 1 && isMappingHeader(topLevel[0].entry, "permissions");
142
- if (exact) {
143
- const entries = [];
144
- for (const line of lines.slice(topLevel[0].index + 1)) {
145
- if (line.trim() === "" || line.trimStart().startsWith("#")) continue;
146
- if (indentation(line) === 0) break;
147
- entries.push(line.trim());
148
- }
149
- exact = entries.length === 1 && entries[0] === "contents: read";
150
- }
151
- if (!exact) failures.push(`${relative}: top-level permissions must be exactly contents: read`);
152
- return failures;
153
- }
154
-
155
- export function workflowActionFailures(workflow, relative) {
156
- const lines = structuralLines(workflow.split("\n"));
157
- return [
158
- ...notationFailures(lines, relative),
159
- ...actionRefFailures(lines, relative),
160
- ...checkoutCredentialFailures(workflow, relative),
161
- ...permissionFailures(lines, relative),
162
- ];
163
- }