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,302 +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 { execFileSync } from "node:child_process";
7
- import { MAX_ARTIFACT_FILE_BYTES } from "./page-artifact-metadata.mjs";
8
- import { canonicalSourceManifest } from "./page-evidence-contract.mjs";
9
- import {
10
- completeSession,
11
- corruptPngCrc,
12
- createConformance,
13
- declareCapturedArtifact,
14
- finalizeSession,
15
- isolated,
16
- pngWithTrailingBytes,
17
- pngWithInvalidImageData,
18
- pngWithTrailingImageData,
19
- receiptFor,
20
- reuseSetup,
21
- rewriteCompletedCapture,
22
- rewriteCompletedArtifact,
23
- semanticEnvironment,
24
- startSession,
25
- started,
26
- truncatedPng,
27
- validateSession,
28
- writeJson,
29
- writeRunner,
30
- } from "./page-evidence-fixture.mjs";
31
-
32
- const requested = [];
33
- let json = false;
34
- for (let index = 2; index < process.argv.length; index += 1) {
35
- const argument = process.argv[index];
36
- if (argument === "--json") json = true;
37
- else if (argument === "--case") {
38
- const value = process.argv[index + 1];
39
- if (value) { requested.push(value); index += 1; }
40
- }
41
- }
42
-
43
- function codes(child) {
44
- return child?.report?.failures?.map((failure) => failure.code) ?? [];
45
- }
46
-
47
- function outcome(name, expected, child, observe = {}) {
48
- const actualCodes = codes(child);
49
- const valid = expected === "ok:true";
50
- const ok = valid ? child?.status === 0 && child.report.ok === true : child?.status !== 0 && actualCodes.includes(expected);
51
- return { actual: { codes: actualCodes, status: child?.status, ...observe }, expected, name, ok };
52
- }
53
-
54
- const cases = {
55
- "complete-session": () => isolated((fixture) => {
56
- const completed = completeSession(fixture);
57
- return outcome("complete-session", "ok:true", completed.validate, {
58
- finalized: completed.finalize?.report.ok === true,
59
- scenarioCount: completed.validate?.report.scenarioCount,
60
- started: completed.start?.report.ok === true,
61
- });
62
- }),
63
- "dirty-relevant-source": () => isolated((fixture) => {
64
- const session = createConformance(fixture);
65
- fs.appendFileSync(path.join(fixture.root, fixture.relevantSources[0]), "// dirty\n");
66
- return outcome("dirty-relevant-source", "page_evidence_source_dirty", startSession(fixture, session));
67
- }),
68
- "untracked-relevant-source": () => isolated((fixture) => {
69
- const session = createConformance(fixture);
70
- const untracked = "src/untracked.js";
71
- fs.writeFileSync(path.join(fixture.root, untracked), "export const untracked = true;\n");
72
- const record = JSON.parse(fs.readFileSync(session.recordFile));
73
- record.consumer.relevant_sources.push(untracked);
74
- const sourceFailures = [];
75
- const source = canonicalSourceManifest(fixture.root, record.consumer.relevant_sources, sourceFailures);
76
- record.scenarios[0].source_digest = source.sha256;
77
- writeJson(session.recordFile, record);
78
- return outcome("untracked-relevant-source", "page_evidence_source_dirty", startSession(fixture, session));
79
- }),
80
- "source-drift-after-start": () => isolated((fixture) => {
81
- const session = started(fixture);
82
- const runner = writeRunner(fixture, session);
83
- fs.appendFileSync(path.join(fixture.root, fixture.relevantSources[0]), "// drift\n");
84
- return outcome("source-drift-after-start", "page_evidence_source_drift", finalizeSession(fixture, session, runner));
85
- }),
86
- "cross-revision": () => isolated((fixture) => {
87
- const session = started(fixture);
88
- const runner = writeRunner(fixture, session, { revision: "0".repeat(40), runRevision: "0".repeat(40) });
89
- return outcome("cross-revision", "page_evidence_revision_mismatch", finalizeSession(fixture, session, runner));
90
- }),
91
- "cross-run": () => isolated((fixture) => {
92
- const session = started(fixture);
93
- const runner = writeRunner(fixture, session, { runId: "different-run" });
94
- return outcome("cross-run", "page_evidence_run_mismatch", finalizeSession(fixture, session, runner));
95
- }),
96
- "cross-session-replay": () => isolated((fixture) => {
97
- const target = started(fixture, { artifactName: "target" });
98
- const alternate = started(fixture, { artifactName: "alternate" });
99
- const targetRunner = writeRunner(fixture, target);
100
- const alternateRunner = writeRunner(fixture, alternate);
101
- fs.copyFileSync(alternateRunner.runnerFile, targetRunner.runnerFile);
102
- fs.copyFileSync(path.join(alternate.artifactRoot, alternateRunner.artifactReference), path.join(target.artifactRoot, targetRunner.artifactReference));
103
- return outcome("cross-session-replay", "page_evidence_session_mismatch", finalizeSession(fixture, target, targetRunner));
104
- }),
105
- "failed-runner": () => isolated((fixture) => {
106
- const session = started(fixture);
107
- const runner = writeRunner(fixture, session, { status: "failed" });
108
- return outcome("failed-runner", "page_evidence_runner_failed", finalizeSession(fixture, session, runner));
109
- }),
110
- "finalize-runner-control-collision": () => isolated((fixture) => {
111
- const session = started(fixture);
112
- const runner = writeRunner(fixture, session);
113
- const declared = declareCapturedArtifact(session, runner, runner.runnerReference);
114
- return outcome("finalize-runner-control-collision", "page_evidence_artifact_control_collision", finalizeSession(fixture, session, declared));
115
- }),
116
- "finalize-receipt-control-collision": () => isolated((fixture) => {
117
- const session = started(fixture);
118
- const runner = writeRunner(fixture, session);
119
- const declared = declareCapturedArtifact(session, runner, "page-evidence-session.json");
120
- return outcome("finalize-receipt-control-collision", "page_evidence_artifact_control_collision", finalizeSession(fixture, session, declared));
121
- }),
122
- "unmanifested-png": () => isolated((fixture) => {
123
- const session = started(fixture);
124
- const runner = writeRunner(fixture, session);
125
- fs.writeFileSync(path.join(session.artifactRoot, "rogue.png"), "rogue");
126
- return outcome("unmanifested-png", "page_evidence_artifact_unmanifested", finalizeSession(fixture, session, runner));
127
- }),
128
- "artifact-tree-depth-limit": () => isolated((fixture) => {
129
- const session = started(fixture);
130
- const runner = writeRunner(fixture, session);
131
- fs.mkdirSync(path.join(session.artifactRoot, ...Array.from({ length: 18 }, (_, index) => `depth-${index}`)), { recursive: true });
132
- return outcome("artifact-tree-depth-limit", "page_evidence_artifact_limit", finalizeSession(fixture, session, runner));
133
- }),
134
- "artifact-entry-limit": () => isolated((fixture) => {
135
- const session = started(fixture);
136
- const runner = writeRunner(fixture, session);
137
- for (let index = 0; index < 4097; index += 1) fs.writeFileSync(path.join(session.artifactRoot, `entry-${index}.txt`), "");
138
- return outcome("artifact-entry-limit", "page_evidence_artifact_limit", finalizeSession(fixture, session, runner));
139
- }),
140
- "artifact-file-byte-limit": () => isolated((fixture) => {
141
- const session = started(fixture);
142
- const runner = writeRunner(fixture, session);
143
- fs.truncateSync(path.join(session.artifactRoot, runner.artifactReference), MAX_ARTIFACT_FILE_BYTES + 1);
144
- return outcome("artifact-file-byte-limit", "page_evidence_artifact_limit", finalizeSession(fixture, session, runner));
145
- }),
146
- "artifact-packet-byte-limit": () => isolated((fixture) => {
147
- const session = started(fixture);
148
- const runner = writeRunner(fixture, session);
149
- for (let index = 0; index < 5; index += 1) {
150
- const file = path.join(session.artifactRoot, `packet-${index}.bin`);
151
- fs.closeSync(fs.openSync(file, "w"));
152
- fs.truncateSync(file, 60 * 1024 * 1024);
153
- }
154
- return outcome("artifact-packet-byte-limit", "page_evidence_artifact_limit", finalizeSession(fixture, session, runner));
155
- }),
156
- "missing-artifact": () => isolated((fixture) => {
157
- const session = started(fixture);
158
- const runner = writeRunner(fixture, session);
159
- fs.rmSync(path.join(session.artifactRoot, runner.artifactReference));
160
- return outcome("missing-artifact", "page_evidence_artifact_missing", finalizeSession(fixture, session, runner));
161
- }),
162
- "truncated-png": () => isolated((fixture) => {
163
- const session = started(fixture);
164
- const runner = writeRunner(fixture, session, { artifactBytes: truncatedPng() });
165
- return outcome("truncated-png", "page_evidence_png_invalid", finalizeSession(fixture, session, runner));
166
- }),
167
- "corrupt-png-crc": () => isolated((fixture) => {
168
- const session = started(fixture);
169
- const runner = writeRunner(fixture, session, { artifactBytes: corruptPngCrc() });
170
- return outcome("corrupt-png-crc", "page_evidence_png_invalid", finalizeSession(fixture, session, runner));
171
- }),
172
- "trailing-png-bytes": () => isolated((fixture) => {
173
- const session = started(fixture);
174
- const runner = writeRunner(fixture, session, { artifactBytes: pngWithTrailingBytes() });
175
- return outcome("trailing-png-bytes", "page_evidence_png_invalid", finalizeSession(fixture, session, runner));
176
- }),
177
- "invalid-png-image-data-finalize": () => isolated((fixture) => {
178
- const session = started(fixture);
179
- const runner = writeRunner(fixture, session, { artifactBytes: pngWithInvalidImageData() });
180
- return outcome("invalid-png-image-data-finalize", "page_evidence_png_invalid", finalizeSession(fixture, session, runner));
181
- }),
182
- "invalid-png-image-data-validate": () => isolated((fixture) => {
183
- const completed = completeSession(fixture);
184
- rewriteCompletedArtifact(completed.session, completed.runner, pngWithInvalidImageData());
185
- return outcome("invalid-png-image-data-validate", "page_evidence_png_invalid", validateSession(fixture, completed.session));
186
- }),
187
- "trailing-png-image-data-finalize": () => isolated((fixture) => {
188
- const session = started(fixture);
189
- const runner = writeRunner(fixture, session, { artifactBytes: pngWithTrailingImageData() });
190
- return outcome("trailing-png-image-data-finalize", "page_evidence_png_invalid", finalizeSession(fixture, session, runner));
191
- }),
192
- "hash-substitution": () => isolated((fixture) => {
193
- const completed = completeSession(fixture);
194
- fs.appendFileSync(path.join(completed.session.artifactRoot, completed.runner.artifactReference), "substitution");
195
- return outcome("hash-substitution", "page_evidence_artifact_integrity", validateSession(fixture, completed.session));
196
- }),
197
- "validate-runner-control-collision": () => isolated((fixture) => {
198
- const completed = completeSession(fixture);
199
- rewriteCompletedCapture(completed.session, completed.runner, completed.runner.runnerReference);
200
- return outcome("validate-runner-control-collision", "page_evidence_artifact_control_collision", validateSession(fixture, completed.session));
201
- }),
202
- "validate-receipt-control-collision": () => isolated((fixture) => {
203
- const completed = completeSession(fixture);
204
- rewriteCompletedCapture(completed.session, completed.runner, "page-evidence-session.json");
205
- return outcome("validate-receipt-control-collision", "page_evidence_artifact_control_collision", validateSession(fixture, completed.session));
206
- }),
207
- "validate-manifest-control-collision": () => isolated((fixture) => {
208
- const completed = completeSession(fixture);
209
- rewriteCompletedCapture(completed.session, completed.runner, "page-evidence-manifest.json");
210
- return outcome("validate-manifest-control-collision", "page_evidence_artifact_control_collision", validateSession(fixture, completed.session));
211
- }),
212
- "artifact-symlink": () => isolated((fixture) => {
213
- const session = started(fixture);
214
- const runner = writeRunner(fixture, session);
215
- const artifact = path.join(session.artifactRoot, runner.artifactReference);
216
- fs.rmSync(artifact);
217
- fs.symlinkSync("/etc/hosts", artifact);
218
- return outcome("artifact-symlink", "page_evidence_artifact_symlink", finalizeSession(fixture, session, runner));
219
- }),
220
- "artifact-redirect": () => isolated((fixture) => {
221
- const completed = completeSession(fixture);
222
- const realRoot = `${completed.session.artifactRoot}-real`;
223
- fs.renameSync(completed.session.artifactRoot, realRoot);
224
- fs.symlinkSync(realRoot, completed.session.artifactRoot);
225
- return outcome("artifact-redirect", "page_evidence_artifact_redirect", validateSession(fixture, completed.session));
226
- }),
227
- "parent-escape": () => isolated((fixture) => {
228
- const session = started(fixture);
229
- const runner = writeRunner(fixture, session, { artifactPath: "../outside.png" });
230
- return outcome("parent-escape", "page_evidence_artifact_escape", finalizeSession(fixture, session, runner));
231
- }),
232
- "capture-outside-session": () => isolated((fixture) => {
233
- const session = started(fixture);
234
- const runner = writeRunner(fixture, session, { recordedAt: "2000-01-01T00:00:00Z" });
235
- return outcome("capture-outside-session", "page_evidence_capture_outside_session", finalizeSession(fixture, session, runner));
236
- }),
237
- "missing-start-receipt": () => isolated((fixture) => {
238
- const completed = completeSession(fixture);
239
- fs.rmSync(path.join(completed.session.artifactRoot, "page-evidence-session.json"));
240
- return outcome("missing-start-receipt", "page_evidence_session_missing", validateSession(fixture, completed.session));
241
- }),
242
- "safe-reuse": () => isolated((fixture) => {
243
- const setup = reuseSetup(fixture);
244
- const runner = writeRunner(fixture, setup.current, { evidence: setup.evidence, writeArtifact: false });
245
- const finalized = finalizeSession(fixture, setup.current, runner, setup.priorManifest);
246
- const validated = finalized.status === 0 ? validateSession(fixture, setup.current, setup.priorManifest) : finalized;
247
- return outcome("safe-reuse", "ok:true", validated, { finalized: finalized.report.ok === true });
248
- }),
249
- "unsafe-reuse": () => isolated((fixture) => {
250
- const setup = reuseSetup(fixture);
251
- setup.evidence.prior_manifest_sha256 = "0".repeat(64);
252
- const runner = writeRunner(fixture, setup.current, { evidence: setup.evidence, writeArtifact: false });
253
- return outcome("unsafe-reuse", "page_evidence_reuse_manifest_mismatch", finalizeSession(fixture, setup.current, runner, setup.priorManifest));
254
- }),
255
- "reuse-source-mismatch": () => isolated((fixture) => {
256
- const setup = reuseSetup(fixture, { beforeCurrent: (consumer) => {
257
- fs.appendFileSync(path.join(consumer.root, consumer.relevantSources[0]), "// next revision\n");
258
- execFileSync("git", ["add", consumer.relevantSources[0]], { cwd: consumer.root });
259
- execFileSync("git", ["commit", "-m", "next fixture revision"], { cwd: consumer.root });
260
- consumer.revision = execFileSync("git", ["rev-parse", "HEAD"], { cwd: consumer.root, encoding: "utf8" }).trim();
261
- } });
262
- const runner = writeRunner(fixture, setup.current, { evidence: setup.evidence, writeArtifact: false });
263
- return outcome("reuse-source-mismatch", "page_evidence_reuse_source_mismatch", finalizeSession(fixture, setup.current, runner, setup.priorManifest));
264
- }),
265
- "reuse-scenario-mismatch": () => isolated((fixture) => {
266
- const setup = reuseSetup(fixture, { currentOptions: { scenarioId: "different-scenario" } });
267
- const runner = writeRunner(fixture, setup.current, { evidence: setup.evidence, writeArtifact: false });
268
- return outcome("reuse-scenario-mismatch", "page_evidence_reuse_scenario_mismatch", finalizeSession(fixture, setup.current, runner, setup.priorManifest));
269
- }),
270
- "reuse-environment-mismatch": () => isolated((fixture) => {
271
- const setup = reuseSetup(fixture);
272
- const changedEnvironment = { ...semanticEnvironment, viewport: { ...semanticEnvironment.viewport, width: 375 } };
273
- const runner = writeRunner(fixture, setup.current, { evidence: setup.evidence, semanticEnvironment: changedEnvironment, writeArtifact: false });
274
- return outcome("reuse-environment-mismatch", "page_evidence_reuse_environment_mismatch", finalizeSession(fixture, setup.current, runner, setup.priorManifest));
275
- }),
276
- "downloaded-unchanged-session": () => isolated((fixture) => {
277
- const completed = completeSession(fixture);
278
- const download = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "stylegallery-page-download-")));
279
- try {
280
- fs.cpSync(fixture.root, download, { recursive: true });
281
- const downloadedFixture = { ...fixture, root: download };
282
- const downloadedSession = { ...completed.session, artifactRoot: completed.session.artifactRoot.replace(fixture.root, download), recordFile: completed.session.recordFile.replace(fixture.root, download) };
283
- return outcome("downloaded-unchanged-session", "ok:true", validateSession(downloadedFixture, downloadedSession));
284
- } finally { fs.rmSync(download, { force: true, recursive: true }); }
285
- }),
286
- "past-review-by-advisory": () => isolated((fixture) => {
287
- const completed = completeSession(fixture);
288
- const manifestFile = path.join(completed.session.artifactRoot, "page-evidence-manifest.json");
289
- const manifest = JSON.parse(fs.readFileSync(manifestFile));
290
- manifest.review_by = "2000-01-01T00:00:00Z";
291
- writeJson(manifestFile, manifest);
292
- return outcome("past-review-by-advisory", "ok:true", validateSession(fixture, completed.session));
293
- }),
294
- };
295
-
296
- const selected = requested.length > 0 ? requested : Object.keys(cases);
297
- const results = selected.map((name) => cases[name]?.() ?? ({ actual: { codes: [], status: null }, expected: "known-case", name, ok: false }));
298
- const failures = results.filter((result) => !result.ok).map((result) => `${result.name}:${result.expected}`);
299
- const report = { adversarial: results.filter((result) => result.expected !== "ok:true").length, failures, ok: failures.length === 0, results };
300
- if (json) process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
301
- else process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
302
- if (!report.ok) process.exitCode = 1;
@@ -1,157 +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-patterns.mjs");
11
- const cases = [
12
- {
13
- name: "missing_metadata",
14
- file: "patterns/stacking/bad.md",
15
- content: "# Bad\n\n## HTML\n\n```html\n<div></div>\n```\n\n## CSS\n\n```css\n.bad {\n display: grid;\n}\n```\n\n## Failure Mode\n\nBad.\n\n## Accessibility Notes\n\nBad.\n",
16
- expect: "missing frontmatter",
17
- },
18
- {
19
- name: "unsorted_css",
20
- file: "patterns/stacking/bad.md",
21
- content: pattern("bad", "Stacking", ".bad {\n width: 100%;\n display: grid;\n}"),
22
- expect: "declarations are not alphabetical",
23
- },
24
- {
25
- name: "forbidden_property",
26
- file: "patterns/stacking/bad.md",
27
- content: pattern("bad", "Stacking", ".bad {\n background: red;\n display: grid;\n}"),
28
- expect: "forbidden decorative property",
29
- },
30
- {
31
- name: "id_selector",
32
- file: "patterns/stacking/bad.md",
33
- content: pattern("bad", "Stacking", "#bad {\n display: grid;\n}"),
34
- expect: "selector uses id",
35
- },
36
- {
37
- name: "missing_html_block",
38
- file: "patterns/stacking/bad.md",
39
- content: pattern("bad", "Stacking", ".bad {\n display: grid;\n}", ""),
40
- expect: "missing html code block",
41
- },
42
- {
43
- name: "missing_css_block",
44
- file: "patterns/stacking/bad.md",
45
- content: pattern("bad", "Stacking", "", "<section class=\"bad\"></section>"),
46
- expect: "missing css code block",
47
- },
48
- {
49
- name: "missing_css_hook_in_html",
50
- file: "patterns/stacking/bad.md",
51
- content: pattern("bad", "Stacking", ".bad {\n display: grid;\n}\n\n.bad_item {\n display: grid;\n}"),
52
- expect: "is missing from HTML block",
53
- },
54
- {
55
- name: "missing_contract_section",
56
- file: "patterns/stacking/bad.md",
57
- content: legacyPattern("bad", "Stacking", ".bad {\n display: grid;\n}"),
58
- expect: "missing Core Properties section",
59
- },
60
- {
61
- name: "missing_accessibility_risk_details",
62
- file: "patterns/stacking/bad.md",
63
- content: pattern("bad", "Stacking", ".bad {\n display: grid;\n}").replace("- DOM order expectation: Keep semantic order.\n", ""),
64
- expectWarning: "missing recommended accessibility detail DOM order expectation:",
65
- },
66
- {
67
- name: "contract_sections_inside_code_block",
68
- file: "patterns/stacking/bad.md",
69
- content: legacyPattern(
70
- "bad",
71
- "Stacking",
72
- ".bad {\n display: grid;\n}\n\n/*\n## Core Properties\n## Properties That Break The Layout If Removed\n## Constraints And Change Points\n## Scroll Ownership\n## Accessibility And Source Order Notes\n## Browser And Fallback Notes\n## Composition Notes\n## Anti-patterns\n*/",
73
- ),
74
- expect: "missing Core Properties section",
75
- },
76
- {
77
- name: "reflow_without_reflow_mechanic",
78
- file: "patterns/split-sidebar/bad.md",
79
- content: pattern("bad", "Split / Sidebar", ".bad {\n display: grid;\n grid-template-columns: 16rem minmax(0, 1fr);\n}", "<section class=\"bad\"><article>Customer queue</article><article>Selected customer</article></section>", "reflow"),
80
- expect: "responsiveness reflow requires",
81
- },
82
- {
83
- name: "reflow_tokens_inside_css_comment",
84
- file: "patterns/split-sidebar/bad.md",
85
- content: pattern("bad", "Split / Sidebar", ".bad {\n display: grid;\n grid-template-columns: 24rem 24rem;\n}\n\n/* auto-fit 100% */", "<section class=\"bad\"><article>Customer queue</article><article>Selected customer</article></section>", "reflow"),
86
- expect: "responsiveness reflow requires",
87
- },
88
- {
89
- name: "unused_html_class",
90
- file: "patterns/stacking/bad.md",
91
- content: pattern("bad", "Stacking", ".bad {\n display: grid;\n}", "<section class=\"bad\"><div class=\"bad_extra\"></div></section>"),
92
- expect: "has no CSS rule",
93
- },
94
- {
95
- name: "placeholder_html",
96
- file: "patterns/stacking/bad.md",
97
- content: pattern("bad", "Stacking", ".bad {\n display: grid;\n}", "<section class=\"bad\"><article>First item</article></section>"),
98
- expect: "placeholder sample phrase",
99
- },
100
- {
101
- name: "success_path",
102
- file: "patterns/stacking/good.md",
103
- content: pattern("good", "Stacking", ".good {\n display: grid;\n gap: 1rem;\n}", "<section class=\"good\"><article>Quarterly review</article></section>"),
104
- expect: null,
105
- },
106
- {
107
- name: "default_min_count",
108
- file: "patterns/stacking/good.md",
109
- content: pattern("good", "Stacking", ".good {\n display: grid;\n gap: 1rem;\n}", "<section class=\"good\"><article>Quarterly review</article></section>"),
110
- expect: null,
111
- useDefaultMinCount: true,
112
- },
113
- ];
114
-
115
- function legacyPattern(name, category, css, html = `<section class="${name}"></section>`, responsiveness = "fluid") {
116
- const cssBlock = css ? `\n\`\`\`css\n${css}\n\`\`\`\n` : "\n";
117
- return `---\nname: ${name}\ncategory: ${category}\nprimary_spatial_problem: Test spatial problem.\nsecondary_spatial_problems: none\nlayout_axis: block\ncontent_shape: mixed\nresponsiveness: ${responsiveness}\nconstraints: Test constraints.\nscroll_ownership: No internal scroll container.\nsource_lineage: test\n---\n\n# ${name}\n\n## When To Use\n\nUse for validation tests.\n\n## HTML\n\n\`\`\`html\n${html}\n\`\`\`\n\n## CSS\n${cssBlock}\n## Failure Mode\n\nBad layout.\n\n## Accessibility Notes\n\nKeep semantic order.\n`;
118
- }
119
-
120
- function pattern(name, category, css, html = `<section class="${name}"></section>`, responsiveness = "fluid") {
121
- const cssBlock = css ? `\n\`\`\`css\n${css}\n\`\`\`\n` : "\n";
122
- return `---\nname: ${name}\ncategory: ${category}\nprimary_spatial_problem: Test spatial problem.\nsecondary_spatial_problems: none\nlayout_axis: block\ncontent_shape: mixed\nresponsiveness: ${responsiveness}\nconstraints: Test constraints.\nscroll_ownership: No internal scroll container.\nsource_lineage: test\n---\n\n# ${name}\n\n## When To Use\n\nUse for validation tests.\n\n## HTML\n\n\`\`\`html\n${html}\n\`\`\`\n\n## CSS\n${cssBlock}\n## Core Properties\n\n- \`display\` establishes the layout context.\n\n## Properties That Break The Layout If Removed\n\n- Removing \`display\` removes the layout behavior.\n\n## Constraints And Change Points\n\nTest constraints.\n\n## Scroll Ownership\n\nNo internal scroll container.\n\n## Accessibility And Source Order Notes\n\n- Semantic role expectation: Preserve the element roles already present in the HTML sample.\n- DOM order expectation: Keep semantic order.\n- Focus risk: Keep focus order aligned with DOM order.\n- Scroll expectation: No internal scroll container.\n- Cognitive risk: Low when the pattern does not reorder meaning or hide controls.\n\n## Browser And Fallback Notes\n\nUse a simpler block fallback when needed.\n\n## Composition Notes\n\nCompose with semantic regions.\n\n## Anti-patterns\n\nDo not use for unrelated visual styling.\n`;
123
- }
124
-
125
- function runCase(testCase) {
126
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), `layout-gallery-${testCase.name}-`));
127
- const absolute = path.join(dir, testCase.file);
128
- fs.mkdirSync(path.dirname(absolute), { recursive: true });
129
- fs.writeFileSync(absolute, testCase.content);
130
- const args = testCase.useDefaultMinCount ? [validator, "--json"] : [validator, "--min-count", "1", "--json"];
131
- const result = spawnSync(process.execPath, args, {
132
- cwd: dir,
133
- encoding: "utf8",
134
- });
135
- fs.rmSync(dir, { force: true, recursive: true });
136
- const output = JSON.parse(result.stdout);
137
- const passed = testCase.expectWarning
138
- ? output.ok && output.warnings?.some((warning) => warning.includes(testCase.expectWarning))
139
- : testCase.expect
140
- ? !output.ok && output.failures.some((failure) => failure.includes(testCase.expect))
141
- : output.ok && (!testCase.useDefaultMinCount || output.minCount === 1);
142
- return {
143
- name: testCase.name,
144
- ok: passed,
145
- expected: testCase.expectWarning ?? testCase.expect ?? "ok:true",
146
- actual: output,
147
- };
148
- }
149
-
150
- const results = cases.map(runCase);
151
- const report = {
152
- ok: results.every((result) => result.ok),
153
- results,
154
- };
155
-
156
- console.log(JSON.stringify(report, null, 2));
157
- process.exitCode = report.ok ? 0 : 1;