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,160 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { canonicalize, hashCanonical } from "./agent-native/canonical-json.mjs";
3
- import {
4
- createManifest,
5
- createStableRef,
6
- createVersionId,
7
- parseStableRef,
8
- parseVersionId,
9
- verifyManifest,
10
- } from "./agent-native/identity.mjs";
11
- import { createImmutableStore } from "./agent-native/immutable-store.mjs";
12
-
13
- class IntegrityAssertionError extends Error {
14
- constructor(message) {
15
- super(message);
16
- this.code = "assertion_failed";
17
- }
18
- }
19
-
20
- function assert(condition, message) {
21
- if (!condition) throw new IntegrityAssertionError(message);
22
- }
23
-
24
- function expectCode(execute, code, message) {
25
- try {
26
- execute();
27
- } catch (error) {
28
- assert(error?.code === code, `${message}: expected ${code}, got ${error?.code}`);
29
- return error.code;
30
- }
31
- throw new IntegrityAssertionError(`${message}: operation succeeded`);
32
- }
33
-
34
- async function runCase(name, expected, execute) {
35
- try {
36
- return { actual: await execute(), expected, name, ok: true };
37
- } catch (error) {
38
- return {
39
- actual: {
40
- code: error?.code ?? "integrity_case_exception",
41
- message: error instanceof Error ? error.message : String(error),
42
- ...(error?.path ? { path: error.path } : {}),
43
- },
44
- expected,
45
- name,
46
- ok: false,
47
- };
48
- }
49
- }
50
-
51
- function versioned(stable_ref, content) {
52
- return { ...content, stable_ref, version_id: createVersionId({ stable_ref, payload: content }) };
53
- }
54
-
55
- export async function runIdentityIntegrityCases() {
56
- const results = [];
57
- results.push(await runCase("canonical_json_is_recursive_and_deterministic", "keys sorted recursively", () => {
58
- const bytes = canonicalize({ z: 2, a: { z: false, b: 1 }, m: [3, { y: 1, x: 0 }] });
59
- assert(bytes === '{"a":{"b":1,"z":false},"m":[3,{"x":0,"y":1}],"z":2}', `unexpected canonical bytes: ${bytes}`);
60
- const hashBytes = canonicalize({ b: 2, a: 1 });
61
- const digest = hashCanonical({ b: 2, a: 1 }).slice("sha256:".length);
62
- assert(digest === createHash("sha256").update(hashBytes).digest("hex"), "canonical hash does not match canonical UTF-8 bytes");
63
- return { bytes, digest };
64
- }));
65
- results.push(await runCase("stable_ref_grammar_and_round_trip", "governed StableRef round-trips", () => {
66
- const stable_ref = createStableRef({ kind: "claim", id: "editorial-layout" });
67
- assert(parseStableRef(stable_ref).id === "editorial-layout", "opaque id was not parsed");
68
- expectCode(() => parseStableRef("claim/editorial layout"), "stable_ref_invalid", "malformed StableRef accepted");
69
- return { stable_ref };
70
- }));
71
- results.push(await runCase("version_id_binds_domain_identity_and_all_content", "StableRef and domain id alter digest", () => {
72
- const first = createVersionId({ stable_ref: "sg:claim/shared", id: "alpha", statement: "same" });
73
- const reordered = createVersionId({ statement: "same", id: "alpha", stable_ref: "sg:claim/shared" });
74
- const second = createVersionId({ stable_ref: "sg:claim/shared", id: "beta", statement: "same" });
75
- const otherRef = createVersionId({ stable_ref: "sg:claim/other", id: "alpha", statement: "same" });
76
- assert(first === reordered, "VersionID depends on object key order");
77
- assert(first !== second, "records differing only by domain id collided");
78
- assert(first.split("@sha256:")[1] !== otherRef.split("@sha256:")[1], "StableRef was absent from digest input");
79
- const parsed = parseVersionId({ version_id: first, stable_ref: "sg:claim/shared", payload: { id: "alpha", statement: "same" } });
80
- assert(parsed.stable_ref === "sg:claim/shared", "VersionID lost its StableRef");
81
- const parsedString = parseVersionId(first);
82
- assert(parsedString.version_id === first && parsedString.stable_ref === "sg:claim/shared", "raw VersionID string did not round-trip");
83
- expectCode(
84
- () => parseVersionId({ version_id: first, payload: { id: "beta", statement: "same" } }),
85
- "version_digest_mismatch",
86
- "changed domain id verified",
87
- );
88
- return { first, second, other_ref: otherRef };
89
- }));
90
- results.push(await runCase("immutable_store_rehashes_every_append", "forged and altered records are rejected", () => {
91
- const store = createImmutableStore();
92
- const valid = versioned("sg:claim/store-fixture", { id: "alpha", nested: { value: "original" } });
93
- const inserted = store.append(valid);
94
- assert(Object.isFrozen(inserted) && Object.isFrozen(inserted.nested), "stored record is not deeply frozen");
95
- try { inserted.nested.value = "tampered"; } catch { /* frozen ESM records throw */ }
96
- assert(inserted.nested.value === "original", "stored nested bytes were mutable");
97
- expectCode(
98
- () => store.append({ ...valid, stable_ref: "sg:claim/forged", version_id: `sg:claim/forged@sha256:${"0".repeat(64)}` }),
99
- "version_digest_mismatch",
100
- "forged VersionID accepted",
101
- );
102
- expectCode(
103
- () => store.append({ ...valid, nested: { value: "tampered" } }),
104
- "version_digest_mismatch",
105
- "altered bytes accepted under an existing VersionID",
106
- );
107
- return { size: store.size, version_id: valid.version_id };
108
- }));
109
- results.push(await runCase("manifest_binds_version_digest_content_digest_and_content", "inline content is checked three ways", () => {
110
- const alphaContent = { id: "alpha", statement: "A" };
111
- const zetaContent = { id: "zeta", statement: "Z" };
112
- const entry = (stable_ref, content) => ({
113
- stable_ref,
114
- content,
115
- content_sha256: hashCanonical(content).slice("sha256:".length),
116
- version_id: createVersionId({ stable_ref, payload: content }),
117
- });
118
- const manifest = createManifest({
119
- manifest_ref: "sg:manifest/identity-fixture",
120
- entries: [entry("sg:claim/zeta", zetaContent), entry("sg:claim/alpha", alphaContent)],
121
- });
122
- assert(manifest.entries[0].stable_ref === "sg:claim/alpha", "entries were not sorted");
123
- assert(new Set(manifest.entries.map(({ stable_ref }) => stable_ref)).size === manifest.entries.length, "entries were not unique");
124
- assert(verifyManifest(manifest).ok, "fresh content-backed manifest failed verification");
125
- expectCode(
126
- () => createManifest({ manifest_ref: "sg:manifest/identity-fixture", entries: [entry("sg:claim/alpha", alphaContent), entry("sg:claim/alpha", alphaContent)] }),
127
- "manifest_entry_duplicate",
128
- "duplicate StableRefs accepted",
129
- );
130
- expectCode(
131
- () => createManifest({ manifest_ref: "sg:manifest/identity-fixture", entries: [{ ...entry("sg:claim/alpha", alphaContent), content: { id: "beta", statement: "A" } }] }),
132
- "version_digest_mismatch",
133
- "VersionID unrelated to inline content accepted",
134
- );
135
- expectCode(
136
- () => createManifest({ manifest_ref: "sg:manifest/identity-fixture", entries: [{ ...entry("sg:claim/alpha", alphaContent), content_sha256: "1".repeat(64) }] }),
137
- "manifest_content_digest_mismatch",
138
- "content digest unrelated to inline content accepted",
139
- );
140
- expectCode(
141
- () => createManifest({ manifest_ref: "sg:manifest/identity-fixture", entries: [{ ...entry("sg:claim/alpha", alphaContent), content: { ...alphaContent, stable_ref: "sg:claim/zeta" } }] }),
142
- "manifest_content_ref_mismatch",
143
- "content carrying a different StableRef accepted",
144
- );
145
- expectCode(
146
- () => createManifest({ manifest_ref: "sg:manifest/identity-fixture", entries: [{ ...entry("sg:claim/alpha", alphaContent), content: { ...alphaContent, version_id: `sg:claim/alpha@sha256:${"0".repeat(64)}` } }] }),
147
- "manifest_content_version_mismatch",
148
- "content carrying a different VersionID accepted",
149
- );
150
- const tampered = structuredClone(manifest);
151
- tampered.entries[0].content.statement = "tampered";
152
- const verification = verifyManifest(tampered);
153
- assert(!verification.ok && verification.failures.some(({ code }) => code === "version_digest_mismatch"), "tampered inline content verified");
154
- const digestTampered = structuredClone(manifest);
155
- digestTampered.sha256 = "0".repeat(64);
156
- assert(!verifyManifest(digestTampered).ok, "tampered manifest digest verified");
157
- return { entries: manifest.entries.length, version_id: manifest.version_id };
158
- }));
159
- return results;
160
- }
@@ -1,183 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import { runIdentityIntegrityCases } from "./test-agent-identity-integrity-cases.mjs";
6
-
7
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
8
- const moduleFiles = Object.freeze({
9
- canonical: "scripts/agent-native/canonical-json.mjs",
10
- identity: "scripts/agent-native/identity.mjs",
11
- store: "scripts/agent-native/immutable-store.mjs",
12
- knowledge: "scripts/agent-native/knowledge.mjs",
13
- });
14
-
15
- function failure(code, message, recordPath) {
16
- return { code, message, ...(recordPath ? { path: recordPath } : {}) };
17
- }
18
-
19
- function valueAt(record, ...keys) {
20
- for (const key of keys) {
21
- if (record && Object.hasOwn(record, key)) return record[key];
22
- }
23
- return undefined;
24
- }
25
-
26
- class ContractError extends Error {
27
- constructor(code, message, recordPath) {
28
- super(message);
29
- this.code = code;
30
- this.path = recordPath;
31
- }
32
- }
33
-
34
- function requireExport(modules, moduleName, names) {
35
- const moduleRecord = modules[moduleName];
36
- if (!moduleRecord || moduleRecord.error) {
37
- const detail = moduleRecord?.error?.message ?? "module was not loaded";
38
- throw new ContractError("kernel_module_missing", `${moduleFiles[moduleName]} is unavailable: ${detail}`, moduleFiles[moduleName]);
39
- }
40
- for (const name of names) {
41
- if (typeof moduleRecord.value?.[name] === "function") return moduleRecord.value[name];
42
- }
43
- throw new ContractError("kernel_export_missing", `${moduleFiles[moduleName]} must export one of ${names.join(", ")}`, moduleFiles[moduleName]);
44
- }
45
-
46
- function assert(condition, message, recordPath) {
47
- if (!condition) throw new ContractError("assertion_failed", message, recordPath);
48
- }
49
-
50
- function resultState(result) {
51
- const state = valueAt(result, "state", "evidence_state", "aggregation", "status");
52
- return typeof state === "string" ? state.toUpperCase() : state;
53
- }
54
-
55
- function makeFixture(modules) {
56
- const claimFactory = requireExport(modules, "knowledge", ["createClaim", "makeClaim"]);
57
- const evidenceFactory = requireExport(modules, "knowledge", ["createEvidenceLink", "makeEvidenceLink"]);
58
- const validationFactory = requireExport(modules, "knowledge", ["createValidationReport", "makeValidationReport"]);
59
- const governanceFactory = requireExport(modules, "knowledge", ["createGovernanceDecision", "makeGovernanceDecision"]);
60
- const claim = claimFactory({
61
- stable_ref: "sg:claim/editorial-layout",
62
- statement: "Editorial layout keeps reading order stable.",
63
- subject: "sg:profile/editorial-reference-profile",
64
- actor: "sg:agent/fixture",
65
- });
66
- const evidence = (polarity, suffix) => evidenceFactory({
67
- stable_ref: `sg:evidence/editorial-layout-${suffix}`,
68
- claim_ref: valueAt(claim, "stable_ref", "stableRef") ?? "sg:claim/editorial-layout",
69
- claim_version: valueAt(claim, "version_id", "versionId"),
70
- source_ref: "sg:artifact/editorial-layout-fixture",
71
- source_version: "sg:artifact/editorial-layout-fixture@sha256:" + "1".repeat(64),
72
- polarity,
73
- independence_group: `fixture-${suffix}`,
74
- actor: `sg:observer/${suffix}`,
75
- });
76
- const validation = validationFactory({
77
- stable_ref: "sg:validation/editorial-layout-pass",
78
- claim_ref: valueAt(claim, "stable_ref", "stableRef"),
79
- claim_version: valueAt(claim, "version_id", "versionId"),
80
- validator: "sg:validator/fixture",
81
- validator_version: "sg:validator/fixture@sha256:" + "2".repeat(64),
82
- status: "PASSED",
83
- inputs: [valueAt(claim, "version_id", "versionId")],
84
- });
85
- const governance = governanceFactory({
86
- stable_ref: "sg:governance/editorial-layout-accept",
87
- claim_ref: valueAt(claim, "stable_ref", "stableRef"),
88
- claim_version: valueAt(claim, "version_id", "versionId"),
89
- actor: "sg:governor/fixture",
90
- decision: "ACCEPTED",
91
- scope: "fixture",
92
- policy_version: "sg:governance-policy/fixture@sha256:" + "3".repeat(64),
93
- });
94
- return { claim, evidence, evidence_sample: evidence("SUPPORT", "fixture"), validation, governance };
95
- }
96
-
97
- async function loadModules() {
98
- const modules = {};
99
- for (const [name, relative] of Object.entries(moduleFiles)) {
100
- try {
101
- modules[name] = { value: await import(path.join(root, relative)) };
102
- } catch (error) {
103
- modules[name] = { error: error instanceof Error ? error : new Error(String(error)) };
104
- }
105
- }
106
- return modules;
107
- }
108
-
109
- async function runCase(name, expected, execute) {
110
- try {
111
- const actual = await execute();
112
- return { actual, expected, name, ok: true };
113
- } catch (error) {
114
- return {
115
- actual: {
116
- code: error instanceof ContractError ? error.code : "kernel_case_exception",
117
- message: error instanceof Error ? error.message : String(error),
118
- ...(error?.path ? { path: error.path } : {}),
119
- },
120
- expected,
121
- name,
122
- ok: false,
123
- };
124
- }
125
- }
126
-
127
- async function main() {
128
- const unsupported = process.argv.slice(2).filter((argument) => argument !== "--json");
129
- if (unsupported.length > 0) {
130
- const report = { ok: false, status: "RED", failures: [failure("argument_unknown", `unknown argument ${unsupported[0]}`)], results: [] };
131
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
132
- process.exitCode = 1;
133
- return;
134
- }
135
-
136
- const modules = await loadModules();
137
- const aggregate = () => requireExport(modules, "knowledge", ["aggregateEvidence", "aggregateEvidenceState"]);
138
-
139
- const results = await runIdentityIntegrityCases();
140
- results.push(await runCase("claim_evidence_validation_governance_are_distinct_frozen_objects", "each epistemic object has its own immutable identity and lifecycle", () => {
141
- const fixture = makeFixture(modules);
142
- for (const [name, value] of Object.entries(fixture)) {
143
- if (name === "evidence") continue;
144
- assert(value && typeof value === "object" && Object.isFrozen(value), `${name} is not deeply frozen`);
145
- assert(typeof valueAt(value, "stable_ref", "stableRef") === "string", `${name} has no StableRef`);
146
- assert(typeof valueAt(value, "version_id", "versionId") === "string", `${name} has no VersionID`);
147
- }
148
- assert(fixture.claim !== fixture.validation && fixture.claim !== fixture.governance, "knowledge layers were conflated");
149
- return { refs: Object.fromEntries(Object.entries(fixture).map(([name, value]) => [name, valueAt(value, "stable_ref", "stableRef")])) };
150
- }));
151
- for (const [name, expectedState, links] of [["supported", "SUPPORTED", ["SUPPORT"]], ["refuted", "REFUTED", ["REFUTE"]], ["both", "BOTH", ["SUPPORT", "REFUTE"]], ["neither", "NEITHER", []]]) {
152
- results.push(await runCase(`evidence_aggregation_${name}`, `aggregation is ${expectedState}`, () => {
153
- const fixture = makeFixture(modules);
154
- const evidence = links.map((polarity, index) => fixture.evidence(polarity, `${name}-${index}`));
155
- const value = aggregate()({ claim: fixture.claim, evidence_links: evidence, evidenceLinks: evidence });
156
- assert(resultState(value) === expectedState, `expected ${expectedState}, got ${resultState(value)}`);
157
- return { state: resultState(value) };
158
- }));
159
- }
160
- results.push(await runCase("validation_and_governance_do_not_erase_contradiction", "validation approval and governance acceptance remain separate from BOTH evidence", () => {
161
- const fixture = makeFixture(modules);
162
- const evidence = [fixture.evidence("SUPPORT", "contradiction-support"), fixture.evidence("REFUTE", "contradiction-refute")];
163
- const before = resultState(aggregate()({ claim: fixture.claim, evidence_links: evidence, evidenceLinks: evidence }));
164
- assert(before === "BOTH", `contradiction fixture did not aggregate BOTH: ${before}`);
165
- assert(valueAt(fixture.validation, "status") === "PASSED", "validation fixture is not passed");
166
- assert(valueAt(fixture.governance, "decision", "status") === "ACCEPTED", "governance fixture is not accepted");
167
- const after = resultState(aggregate()({ claim: fixture.claim, evidence_links: evidence, evidenceLinks: evidence }));
168
- assert(after === "BOTH", `validation/governance erased contradiction: ${after}`);
169
- return { before, after, validation: valueAt(fixture.validation, "status"), governance: valueAt(fixture.governance, "decision", "status") };
170
- }));
171
-
172
- const ok = results.every((result) => result.ok);
173
- const report = {
174
- ok,
175
- status: ok ? "GREEN" : "RED",
176
- modules: Object.fromEntries(Object.entries(modules).map(([name, loaded]) => [name, loaded.error ? { ok: false, error: loaded.error.message } : { ok: true }])),
177
- results,
178
- };
179
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
180
- process.exitCode = ok ? 0 : 1;
181
- }
182
-
183
- await main();
@@ -1,246 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createVersionId, parseVersionId } from "./agent-native/identity.mjs";
3
- import {
4
- createProposal,
5
- decideProposal,
6
- promoteProposal,
7
- verifyProposal,
8
- } from "./agent-native/learning.mjs";
9
-
10
- function omitVersion(record) {
11
- const payload = structuredClone(record);
12
- delete payload.version_id;
13
- delete payload.versionId;
14
- return payload;
15
- }
16
-
17
- function reversion(record, changes) {
18
- const payload = { ...omitVersion(record), ...changes };
19
- return {
20
- ...payload,
21
- version_id: createVersionId({ stable_ref: payload.stable_ref, payload }),
22
- };
23
- }
24
-
25
- function isVersioned(record, kind) {
26
- if (!record || record.record_kind !== kind || typeof record.version_id !== "string") return false;
27
- try {
28
- parseVersionId({
29
- payload: omitVersion(record),
30
- stable_ref: record.stable_ref,
31
- version_id: record.version_id,
32
- });
33
- return Object.isFrozen(record);
34
- } catch {
35
- return false;
36
- }
37
- }
38
-
39
- function rejected(call) {
40
- try {
41
- const value = call();
42
- return value?.promoted !== true && (value?.ok === false || value?.status === "BLOCKED");
43
- } catch (error) {
44
- return typeof error?.code === "string" && error.code.startsWith("learning_");
45
- }
46
- }
47
-
48
- function result(id, ok, detail) {
49
- return { id, ok, detail };
50
- }
51
-
52
- const proposalInput = {
53
- claim: {
54
- stable_ref: "sg:claim/retrieval-improvement",
55
- text: "The retriever preserves citation coverage.",
56
- },
57
- changes: [{ path: "retriever.strategy", value: "hybrid" }],
58
- evidence: [{
59
- independence_group: "capture-a",
60
- source_ref: "sg:source/execution-fixture",
61
- stable_ref: "sg:evidence/retrieval-proposal",
62
- }],
63
- proposer: "agent:proposer",
64
- proposal_id: "sg:proposal/retrieval-improvement",
65
- source_task: "sg:task/execution-fixture",
66
- validation: {
67
- status: "PASS",
68
- validator: "agent:proposal-validator",
69
- validator_version: "validator@v1",
70
- },
71
- };
72
-
73
- const proposal = createProposal(proposalInput);
74
- const verification = verifyProposal({
75
- evidence: [{
76
- independence_group: "capture-b",
77
- source_ref: "sg:source/independent-fixture",
78
- stable_ref: "sg:evidence/retrieval-verification",
79
- }],
80
- independent_of: "agent:proposer",
81
- proposal,
82
- validation: {
83
- status: "PASS",
84
- validator: "agent:independent-validator",
85
- validator_version: "validator@v2",
86
- },
87
- verifier: "agent:verifier",
88
- });
89
- const decision = decideProposal({
90
- decision: "ACCEPT",
91
- governance_decision: {
92
- actor: "governor:review-board",
93
- decided_at: "2026-07-23T00:00:00.000Z",
94
- },
95
- proposal,
96
- verification,
97
- });
98
-
99
- const validPromotion = promoteProposal({
100
- governance_decision: decision,
101
- proposal,
102
- verification,
103
- });
104
- const proposalV2 = createProposal({
105
- ...proposalInput,
106
- changes: [{ path: "retriever.strategy", value: "semantic" }],
107
- });
108
- const forgedProposal = {
109
- ...structuredClone(proposal),
110
- changes: [{ path: "retriever.strategy", value: "forged" }],
111
- };
112
- const forgedVerification = {
113
- ...structuredClone(verification),
114
- verifier: "agent:forger",
115
- verifier_actor: "agent:forger",
116
- };
117
- const wrongKindVerification = reversion(verification, {
118
- record_kind: "evidence_link",
119
- });
120
- const wrongLinkDecision = reversion(decision, {
121
- verification_ref: "sg:validation/unrelated-verification",
122
- });
123
- const wrongKindDecision = reversion(decision, {
124
- record_kind: "learning_verification",
125
- });
126
- const forgedDecision = {
127
- ...structuredClone(decision),
128
- actor: "governor:forger",
129
- };
130
- const aliasInjectedDecision = {
131
- ...structuredClone(decision),
132
- versionId: `sg:governance/alias@sha256:${"0".repeat(64)}`,
133
- };
134
- const tamperedEvidence = structuredClone(verification.evidence);
135
- tamperedEvidence[0].source_ref = "sg:source/tampered-fixture";
136
- const verificationWithTamperedEvidence = reversion(verification, {
137
- evidence: tamperedEvidence,
138
- });
139
-
140
- const rows = [
141
- result(
142
- "immutable_chain_is_fully_versioned",
143
- isVersioned(proposal, "learning_proposal")
144
- && proposal.evidence.every((item) => isVersioned(item, "evidence_link"))
145
- && isVersioned(proposal.validation, "validation_report")
146
- && isVersioned(verification, "learning_verification")
147
- && verification.evidence.every((item) => isVersioned(item, "evidence_link"))
148
- && isVersioned(verification.validation, "validation_report")
149
- && isVersioned(decision, "governance_decision")
150
- && decision.proposal_version_id === proposal.version_id
151
- && decision.verification_version_id === verification.version_id,
152
- "proposal, evidence, validation, verification, and decision have content-bound VersionIDs",
153
- ),
154
- result(
155
- "valid_independent_chain_promotes",
156
- validPromotion.promoted === true
157
- && isVersioned(validPromotion.version, "governed_version")
158
- && validPromotion.version.proposal_version_id === proposal.version_id
159
- && validPromotion.version.verification_version_id === verification.version_id
160
- && validPromotion.version.governance_decision_version_id === decision.version_id,
161
- "a correctly linked independent chain produces one governed version",
162
- ),
163
- result(
164
- "self_verification_is_rejected",
165
- rejected(() => verifyProposal({
166
- evidence: proposalInput.evidence,
167
- proposal,
168
- validation: proposalInput.validation,
169
- verifier: "agent:proposer",
170
- })),
171
- "the proposer cannot verify its own proposal",
172
- ),
173
- result(
174
- "whitespace_cannot_bypass_self_verification",
175
- rejected(() => verifyProposal({
176
- evidence: proposalInput.evidence,
177
- proposal,
178
- validation: proposalInput.validation,
179
- verifier: " agent:proposer ",
180
- })),
181
- "actor identity is canonicalized before the independence comparison",
182
- ),
183
- result(
184
- "forged_proposal_bytes_are_rejected",
185
- rejected(() => promoteProposal({ governance_decision: decision, proposal: forgedProposal, verification })),
186
- "changing proposal bytes without minting a matching VersionID is rejected",
187
- ),
188
- result(
189
- "forged_verification_bytes_are_rejected",
190
- rejected(() => promoteProposal({ governance_decision: decision, proposal, verification: forgedVerification })),
191
- "changing verification bytes without minting a matching VersionID is rejected",
192
- ),
193
- result(
194
- "stale_verification_is_rejected",
195
- rejected(() => promoteProposal({ governance_decision: decision, proposal: proposalV2, verification })),
196
- "verification and governance for an older proposal version cannot promote a newer proposal",
197
- ),
198
- result(
199
- "wrong_kind_verification_is_rejected",
200
- rejected(() => promoteProposal({ governance_decision: decision, proposal, verification: wrongKindVerification })),
201
- "a content-valid record with the wrong semantic kind cannot stand in for verification",
202
- ),
203
- result(
204
- "wrong_governance_link_is_rejected",
205
- rejected(() => promoteProposal({ governance_decision: wrongLinkDecision, proposal, verification })),
206
- "governance must bind the exact verification StableRef and VersionID",
207
- ),
208
- result(
209
- "wrong_kind_governance_is_rejected",
210
- rejected(() => promoteProposal({ governance_decision: wrongKindDecision, proposal, verification })),
211
- "a content-valid record with the wrong semantic kind cannot stand in for governance",
212
- ),
213
- result(
214
- "forged_governance_bytes_are_rejected",
215
- rejected(() => promoteProposal({ governance_decision: forgedDecision, proposal, verification })),
216
- "changing governance bytes without minting a matching VersionID is rejected",
217
- ),
218
- result(
219
- "nested_evidence_bytes_are_rejected",
220
- rejected(() => promoteProposal({ governance_decision: decision, proposal, verification: verificationWithTamperedEvidence })),
221
- "an outer-valid verification cannot hide evidence whose bytes no longer match its VersionID",
222
- ),
223
- result(
224
- "unbound_identity_alias_is_rejected",
225
- rejected(() => promoteProposal({ governance_decision: aliasInjectedDecision, proposal, verification })),
226
- "canonical learning records reject alternate identity fields that are not part of their VersionID",
227
- ),
228
- result(
229
- "verification_actor_cannot_govern_same_proposal",
230
- rejected(() => decideProposal({
231
- decision: "ACCEPT",
232
- governance_decision: { actor: "agent:verifier" },
233
- proposal,
234
- verification,
235
- })),
236
- "independent verification and governance remain separate actors",
237
- ),
238
- ];
239
-
240
- const report = {
241
- contract: "agent-native-governed-learning-integrity",
242
- ok: rows.every((row) => row.ok),
243
- results: rows,
244
- };
245
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
246
- process.exitCode = report.ok ? 0 : 1;