stylegallery 0.1.0

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 (346) hide show
  1. package/AGENTS.md +156 -0
  2. package/CATALOG.md +69 -0
  3. package/DOMAINS.md +65 -0
  4. package/GOVERNANCE.md +222 -0
  5. package/GUIDE.md +59 -0
  6. package/README.md +313 -0
  7. package/consumer-reference/adapters/style-dictionary.config.mjs +36 -0
  8. package/consumer-reference/agent-native/README.md +157 -0
  9. package/consumer-reference/agent-native/registry.json +640 -0
  10. package/consumer-reference/agent-native/schema/agent-native.schema.json +848 -0
  11. package/consumer-reference/agent-native/schema/epistemic.schema.json +14 -0
  12. package/consumer-reference/agent-native/schema/execution.schema.json +12 -0
  13. package/consumer-reference/agent-native/schema/identity.schema.json +10 -0
  14. package/consumer-reference/agent-native/schema/learning.schema.json +12 -0
  15. package/consumer-reference/agent-native/schema/manifest.schema.json +6 -0
  16. package/consumer-reference/agent-native/schema/operation.schema.json +12 -0
  17. package/consumer-reference/agent-native/schema/protocol-binding.schema.json +9 -0
  18. package/consumer-reference/agent-native/schema/retrieval.schema.json +10 -0
  19. package/consumer-reference/baselines/calibration.json +260 -0
  20. package/consumer-reference/baselines/manifest.json +21 -0
  21. package/consumer-reference/contract.md +83 -0
  22. package/consumer-reference/fixtures/consumer-conformance/e2e-fixture.mjs +282 -0
  23. package/consumer-reference/fixtures/consumer-conformance/manifest.json +102 -0
  24. package/consumer-reference/fixtures/consumer-conformance/runtime-proof.mjs +32 -0
  25. package/consumer-reference/fixtures/consumer-conformance/valid-migration-result.json +18 -0
  26. package/consumer-reference/fixtures/consumer-conformance/valid-migration.json +142 -0
  27. package/consumer-reference/fixtures/invalid-stable-ended-support.json +19 -0
  28. package/consumer-reference/fixtures/promotion/invalid-blocking-evidence.json +26 -0
  29. package/consumer-reference/fixtures/promotion/invalid-count-only.json +29 -0
  30. package/consumer-reference/fixtures/promotion/invalid-missing-owner-migration.json +25 -0
  31. package/consumer-reference/fixtures/promotion/invalid-normative-bypass-no-regression.json +25 -0
  32. package/consumer-reference/fixtures/promotion/invalid-related-counted-independent.json +45 -0
  33. package/consumer-reference/fixtures/promotion/invalid-stable-ended-support.json +26 -0
  34. package/consumer-reference/fixtures/promotion/manifest.json +15 -0
  35. package/consumer-reference/fixtures/promotion/valid-deferred-example.json +67 -0
  36. package/consumer-reference/fixtures/promotion/valid-normative-bypass.json +67 -0
  37. package/consumer-reference/fixtures/token-portability/invalid-cycle.json +7 -0
  38. package/consumer-reference/fixtures/token-portability/invalid-dangling-alias.json +6 -0
  39. package/consumer-reference/fixtures/token-portability/invalid-extends.json +4 -0
  40. package/consumer-reference/fixtures/token-portability/invalid-json-pointer.json +7 -0
  41. package/consumer-reference/fixtures/token-portability/invalid-resolver.json +9 -0
  42. package/consumer-reference/fixtures/token-portability/invalid-type-mismatch.json +10 -0
  43. package/consumer-reference/fixtures/token-portability/invalid-unknown-reserved.json +6 -0
  44. package/consumer-reference/fixtures/token-portability/invalid-untested-type.json +6 -0
  45. package/consumer-reference/fixtures/token-portability/valid-border.json +14 -0
  46. package/consumer-reference/fixtures/token-portability/valid-reference.json +32 -0
  47. package/consumer-reference/fixtures/token-portability/valid-whole-alias.json +7 -0
  48. package/consumer-reference/fixtures/valid-deprecated.json +21 -0
  49. package/consumer-reference/fixtures/valid-experimental.json +19 -0
  50. package/consumer-reference/generated/manifest.json +40 -0
  51. package/consumer-reference/generated/tokens.css +12 -0
  52. package/consumer-reference/index.md +32 -0
  53. package/consumer-reference/policies/shared-experimental.json +37 -0
  54. package/consumer-reference/schema/ax-evidence.schema.json +30 -0
  55. package/consumer-reference/schema/baseline-manifest.schema.json +55 -0
  56. package/consumer-reference/schema/calibration-record.schema.json +190 -0
  57. package/consumer-reference/schema/capture-session.schema.json +161 -0
  58. package/consumer-reference/schema/component-state.schema.json +150 -0
  59. package/consumer-reference/schema/consumer-conformance-record.schema.json +365 -0
  60. package/consumer-reference/schema/dom-evidence.schema.json +38 -0
  61. package/consumer-reference/schema/evidence-record.schema.json +81 -0
  62. package/consumer-reference/schema/fixture-manifest.schema.json +32 -0
  63. package/consumer-reference/schema/item.schema.json +188 -0
  64. package/consumer-reference/schema/page-evidence-manifest.schema.json +216 -0
  65. package/consumer-reference/schema/page-evidence-session.schema.json +119 -0
  66. package/consumer-reference/schema/portable-tokens.schema.json +104 -0
  67. package/consumer-reference/schema/promotion-rfc.schema.json +219 -0
  68. package/consumer-reference/schema/runtime-evidence-manifest.schema.json +33 -0
  69. package/consumer-reference/schema/visual-evidence.schema.json +31 -0
  70. package/design-engineering/consumer-migration-readiness.md +124 -0
  71. package/design-engineering/index.md +28 -0
  72. package/design-engineering/interface-craft.md +107 -0
  73. package/design-engineering/reference-profiles/external-adaptation/index.md +12 -0
  74. package/design-engineering/reference-profiles/governed-local/editorial/components/button.component.json +125 -0
  75. package/design-engineering/reference-profiles/governed-local/editorial/evidence/button.evidence.json +3504 -0
  76. package/design-engineering/reference-profiles/governed-local/editorial/fixtures/button.fixture.json +65 -0
  77. package/design-engineering/reference-profiles/governed-local/editorial/generated/evidence-coverage.md +23 -0
  78. package/design-engineering/reference-profiles/governed-local/editorial/generated/keyboard-matrix.md +19 -0
  79. package/design-engineering/reference-profiles/governed-local/editorial/generated/state-matrix.md +21 -0
  80. package/design-engineering/reference-profiles/governed-local/editorial/local-foundations.json +12 -0
  81. package/design-engineering/reference-profiles/governed-local/editorial/profile.json +43 -0
  82. package/design-engineering/reference-profiles/governed-local/editorial/states/button.states.json +195 -0
  83. package/design-engineering/reference-profiles/governed-local/editorial/tokens.dtcg.json +17 -0
  84. package/design-engineering/reference-profiles/governed-local/index.md +26 -0
  85. package/design-engineering/reference-profiles/governed-local/terminal/components/button.component.json +125 -0
  86. package/design-engineering/reference-profiles/governed-local/terminal/evidence/button.evidence.json +3504 -0
  87. package/design-engineering/reference-profiles/governed-local/terminal/fixtures/button.fixture.json +65 -0
  88. package/design-engineering/reference-profiles/governed-local/terminal/generated/evidence-coverage.md +23 -0
  89. package/design-engineering/reference-profiles/governed-local/terminal/generated/keyboard-matrix.md +19 -0
  90. package/design-engineering/reference-profiles/governed-local/terminal/generated/state-matrix.md +21 -0
  91. package/design-engineering/reference-profiles/governed-local/terminal/local-foundations.json +12 -0
  92. package/design-engineering/reference-profiles/governed-local/terminal/profile.json +43 -0
  93. package/design-engineering/reference-profiles/governed-local/terminal/states/button.states.json +195 -0
  94. package/design-engineering/reference-profiles/governed-local/terminal/tokens.dtcg.json +17 -0
  95. package/design-engineering/reference-profiles/index.md +19 -0
  96. package/game-ui/classification.md +82 -0
  97. package/game-ui/index.md +35 -0
  98. package/game-ui/reference-record.md +62 -0
  99. package/game-ui/screen-hierarchy.md +107 -0
  100. package/game-ui/unity/architecture.md +166 -0
  101. package/game-ui/unity/cli-loop.md +84 -0
  102. package/game-ui/unity/data/unity-technologies-public-repositories.json +26654 -0
  103. package/game-ui/unity/org-wiki.md +146 -0
  104. package/game-ui/unity/repository-map.md +102 -0
  105. package/game-ui/unity/ui-systems.md +85 -0
  106. package/guides/decision-tree.md +149 -0
  107. package/guides/documentation-mode-taxonomy.md +157 -0
  108. package/guides/layout-brief.md +220 -0
  109. package/guides/vocabulary.md +148 -0
  110. package/guides/webpage-generation-workflow.md +185 -0
  111. package/index.md +36 -0
  112. package/layout/index.md +26 -0
  113. package/motion/index.md +24 -0
  114. package/motion/practice-reference.md +145 -0
  115. package/motion/review-workflow.md +86 -0
  116. package/motion/vocabulary.md +82 -0
  117. package/package.json +78 -0
  118. package/patterns/centering/center.md +87 -0
  119. package/patterns/centering/index.md +6 -0
  120. package/patterns/centering/super-center.md +89 -0
  121. package/patterns/containment/box.md +87 -0
  122. package/patterns/containment/clamped-card.md +86 -0
  123. package/patterns/containment/content-limiter.md +87 -0
  124. package/patterns/containment/fluid-styles.md +86 -0
  125. package/patterns/containment/index.md +8 -0
  126. package/patterns/grid-repetition/card-grid.md +88 -0
  127. package/patterns/grid-repetition/columns.md +87 -0
  128. package/patterns/grid-repetition/dense-grid.md +88 -0
  129. package/patterns/grid-repetition/grid-wrapper.md +89 -0
  130. package/patterns/grid-repetition/index.md +12 -0
  131. package/patterns/grid-repetition/masonry-approx.md +87 -0
  132. package/patterns/grid-repetition/page-grid.md +90 -0
  133. package/patterns/grid-repetition/ram-grid.md +88 -0
  134. package/patterns/grid-repetition/twelve-span-grid.md +92 -0
  135. package/patterns/in-line-grouping/badge-list.md +94 -0
  136. package/patterns/in-line-grouping/breadcrumb.md +89 -0
  137. package/patterns/in-line-grouping/cluster.md +89 -0
  138. package/patterns/in-line-grouping/deconstructed-pancake.md +92 -0
  139. package/patterns/in-line-grouping/index.md +13 -0
  140. package/patterns/in-line-grouping/pagination.md +89 -0
  141. package/patterns/in-line-grouping/reel.md +90 -0
  142. package/patterns/in-line-grouping/split-nav.md +97 -0
  143. package/patterns/in-line-grouping/tab-strip.md +88 -0
  144. package/patterns/in-line-grouping/wrap-row.md +89 -0
  145. package/patterns/index.md +13 -0
  146. package/patterns/media-fit/frame.md +95 -0
  147. package/patterns/media-fit/icon-frame.md +87 -0
  148. package/patterns/media-fit/index.md +6 -0
  149. package/patterns/overlay-exception/imposter.md +95 -0
  150. package/patterns/overlay-exception/index.md +6 -0
  151. package/patterns/overlay-exception/overlay-stack.md +89 -0
  152. package/patterns/split-sidebar/index.md +12 -0
  153. package/patterns/split-sidebar/list-detail.md +95 -0
  154. package/patterns/split-sidebar/main-with-rail.md +95 -0
  155. package/patterns/split-sidebar/media-object.md +102 -0
  156. package/patterns/split-sidebar/sidebar.md +101 -0
  157. package/patterns/split-sidebar/split-screen.md +92 -0
  158. package/patterns/split-sidebar/sticky-aside.md +97 -0
  159. package/patterns/split-sidebar/supporting-pane.md +95 -0
  160. package/patterns/split-sidebar/switcher.md +93 -0
  161. package/patterns/stacking/feed.md +88 -0
  162. package/patterns/stacking/index.md +8 -0
  163. package/patterns/stacking/line-up.md +95 -0
  164. package/patterns/stacking/stack.md +87 -0
  165. package/patterns/stacking/step-nav.md +88 -0
  166. package/patterns/viewport-shell/cover.md +90 -0
  167. package/patterns/viewport-shell/fixed-sidenav-shell.md +97 -0
  168. package/patterns/viewport-shell/holy-grail.md +112 -0
  169. package/patterns/viewport-shell/index.md +11 -0
  170. package/patterns/viewport-shell/panel-layout.md +95 -0
  171. package/patterns/viewport-shell/scroll-body-shell.md +93 -0
  172. package/patterns/viewport-shell/sticky-footer.md +92 -0
  173. package/patterns/viewport-shell/sticky-header.md +86 -0
  174. package/platform-guides/apple-interaction.md +89 -0
  175. package/platform-guides/index.md +26 -0
  176. package/quality/claim-records/index.md +3 -0
  177. package/quality/claim-records/samples.md +92 -0
  178. package/quality/claim-records/stylegallery-multidomain-scope.md +42 -0
  179. package/quality/claims.md +77 -0
  180. package/quality/evidence/accessibility.md +58 -0
  181. package/quality/evidence/consumer-migration.md +42 -0
  182. package/quality/evidence/design-rationale.md +34 -0
  183. package/quality/evidence/executable-evidence.md +79 -0
  184. package/quality/evidence/families.md +56 -0
  185. package/quality/evidence/hci-evaluation.md +36 -0
  186. package/quality/evidence/index.md +16 -0
  187. package/quality/evidence/pattern-contract-audit.md +96 -0
  188. package/quality/evidence/search-metadata-polyhierarchy.md +86 -0
  189. package/quality/evidence/sources.md +43 -0
  190. package/quality/evidence/tokens.md +33 -0
  191. package/quality/evidence/visual-qa.md +41 -0
  192. package/quality/gates/accessibility-evidence.md +60 -0
  193. package/quality/gates/consumer-migration-evidence.md +53 -0
  194. package/quality/gates/design-claim.md +56 -0
  195. package/quality/gates/harmony-evaluation.md +78 -0
  196. package/quality/gates/index.md +13 -0
  197. package/quality/gates/layout.md +52 -0
  198. package/quality/gates/rationale.md +53 -0
  199. package/quality/gates/visual-evidence.md +47 -0
  200. package/quality/index.md +55 -0
  201. package/quality/principles.md +58 -0
  202. package/recipes/article-page.md +52 -0
  203. package/recipes/command-surface.md +55 -0
  204. package/recipes/dashboard.md +56 -0
  205. package/recipes/form-flow.md +55 -0
  206. package/recipes/homepage.md +89 -0
  207. package/recipes/index.md +13 -0
  208. package/recipes/list-detail.md +55 -0
  209. package/recipes/primitive-to-recipe-matrix.md +83 -0
  210. package/recipes/saas-settings.md +52 -0
  211. package/scripts/agent-native/a2a-projection.mjs +248 -0
  212. package/scripts/agent-native/agui-projection.mjs +178 -0
  213. package/scripts/agent-native/canonical-json.mjs +109 -0
  214. package/scripts/agent-native/cli-adapter.mjs +68 -0
  215. package/scripts/agent-native/events.mjs +113 -0
  216. package/scripts/agent-native/execution.mjs +227 -0
  217. package/scripts/agent-native/fixture.mjs +159 -0
  218. package/scripts/agent-native/identity.mjs +184 -0
  219. package/scripts/agent-native/immutable-store.mjs +102 -0
  220. package/scripts/agent-native/knowledge.mjs +168 -0
  221. package/scripts/agent-native/learning-records.mjs +244 -0
  222. package/scripts/agent-native/learning.mjs +247 -0
  223. package/scripts/agent-native/mcp-adapter.mjs +173 -0
  224. package/scripts/agent-native/queries.mjs +173 -0
  225. package/scripts/agent-native/registry.mjs +154 -0
  226. package/scripts/agent-native/retrieval.mjs +171 -0
  227. package/scripts/agent-native/self-description.mjs +160 -0
  228. package/scripts/artifact-metadata.mjs +20 -0
  229. package/scripts/audit-evidence-freshness.mjs +308 -0
  230. package/scripts/baseline-contract.mjs +189 -0
  231. package/scripts/baseline-schema-parity.mjs +40 -0
  232. package/scripts/build-reference-artifacts.mjs +127 -0
  233. package/scripts/calibration-raw-contract.mjs +172 -0
  234. package/scripts/capture-session-contract.mjs +187 -0
  235. package/scripts/component-state-artifact-fixture.mjs +44 -0
  236. package/scripts/component-state-contract.mjs +99 -0
  237. package/scripts/component-state-semantics.mjs +128 -0
  238. package/scripts/component-state-workflow-contract.mjs +67 -0
  239. package/scripts/component-state-workflow-negative-cases.mjs +64 -0
  240. package/scripts/consumer-conformance-contract.mjs +198 -0
  241. package/scripts/consumer-evidence-governance-contract.mjs +210 -0
  242. package/scripts/consumer-reference-case-runner.mjs +93 -0
  243. package/scripts/consumer-reference-schema.mjs +155 -0
  244. package/scripts/create-component-state-session.mjs +100 -0
  245. package/scripts/create-page-evidence-session.mjs +139 -0
  246. package/scripts/domain-document-boundaries.mjs +40 -0
  247. package/scripts/domain-validation-checks.mjs +141 -0
  248. package/scripts/evidence-artifact-contract.mjs +191 -0
  249. package/scripts/finalize-component-state-evidence.mjs +165 -0
  250. package/scripts/finalize-page-evidence.mjs +197 -0
  251. package/scripts/generate-consumer-reference-evidence.mjs +154 -0
  252. package/scripts/generate-patterns.mjs +218 -0
  253. package/scripts/governance-matrix-contract.mjs +73 -0
  254. package/scripts/governance-matrix-negative-cases.mjs +114 -0
  255. package/scripts/governance-policy-contract.mjs +49 -0
  256. package/scripts/governance-test-fixture.mjs +321 -0
  257. package/scripts/governance-workflow-negative-cases.mjs +241 -0
  258. package/scripts/governed-profile-registry.mjs +125 -0
  259. package/scripts/json-schema-formats.mjs +31 -0
  260. package/scripts/markdown-structure.mjs +45 -0
  261. package/scripts/page-artifact-metadata.mjs +124 -0
  262. package/scripts/page-evidence-contract.mjs +297 -0
  263. package/scripts/page-evidence-fixture.mjs +271 -0
  264. package/scripts/pattern-data.mjs +325 -0
  265. package/scripts/profile-record-contract.mjs +140 -0
  266. package/scripts/promotion-attestation-contract.mjs +91 -0
  267. package/scripts/promotion-boundary-test-contract.mjs +92 -0
  268. package/scripts/promotion-fixture-inventory.mjs +109 -0
  269. package/scripts/promotion-governance-contract.mjs +28 -0
  270. package/scripts/reference-artifact-path-contract.mjs +28 -0
  271. package/scripts/reference-profile-contract.mjs +114 -0
  272. package/scripts/reference-token-contract.mjs +156 -0
  273. package/scripts/run-consumer-page-evidence-ci.mjs +170 -0
  274. package/scripts/sg-mcp.mjs +16 -0
  275. package/scripts/sg.mjs +27 -0
  276. package/scripts/strict-json.mjs +72 -0
  277. package/scripts/summarize-sentinel-calibration.mjs +98 -0
  278. package/scripts/test-agent-adapter-conformance.mjs +250 -0
  279. package/scripts/test-agent-conformance-receipt.mjs +106 -0
  280. package/scripts/test-agent-events.mjs +81 -0
  281. package/scripts/test-agent-execution-effects.mjs +114 -0
  282. package/scripts/test-agent-execution-fixtures.mjs +140 -0
  283. package/scripts/test-agent-execution-kernel.mjs +39 -0
  284. package/scripts/test-agent-execution-learning.mjs +130 -0
  285. package/scripts/test-agent-execution-lifecycle.mjs +143 -0
  286. package/scripts/test-agent-execution-safety.mjs +158 -0
  287. package/scripts/test-agent-execution-views.mjs +117 -0
  288. package/scripts/test-agent-identity-integrity-cases.mjs +160 -0
  289. package/scripts/test-agent-knowledge-kernel.mjs +183 -0
  290. package/scripts/test-agent-learning.mjs +246 -0
  291. package/scripts/test-agent-mcp.mjs +246 -0
  292. package/scripts/test-agent-native-schemas.mjs +215 -0
  293. package/scripts/test-agent-projections.mjs +249 -0
  294. package/scripts/test-agent-registry-mcp-integrity.mjs +215 -0
  295. package/scripts/test-agent-registry-mutations.mjs +110 -0
  296. package/scripts/test-audit-evidence-freshness.mjs +177 -0
  297. package/scripts/test-component-state-sentinel.mjs +35 -0
  298. package/scripts/test-component-state-source-contract.mjs +83 -0
  299. package/scripts/test-consumer-conformance-sentinel.mjs +165 -0
  300. package/scripts/test-consumer-reference-sentinel.mjs +31 -0
  301. package/scripts/test-generate-consumer-reference-evidence.mjs +124 -0
  302. package/scripts/test-json-cli-output.mjs +151 -0
  303. package/scripts/test-json-schema-formats.mjs +40 -0
  304. package/scripts/test-reference-adapters.mjs +199 -0
  305. package/scripts/test-renderer-purity.mjs +34 -0
  306. package/scripts/test-sg-cli.mjs +129 -0
  307. package/scripts/test-summarize-sentinel-calibration.mjs +226 -0
  308. package/scripts/test-validate-baseline-manifest.mjs +234 -0
  309. package/scripts/test-validate-component-state-artifacts.mjs +243 -0
  310. package/scripts/test-validate-component-state.mjs +106 -0
  311. package/scripts/test-validate-consumer-conformance.mjs +427 -0
  312. package/scripts/test-validate-consumer-reference-cli.mjs +69 -0
  313. package/scripts/test-validate-consumer-reference.mjs +263 -0
  314. package/scripts/test-validate-domains.mjs +357 -0
  315. package/scripts/test-validate-governance.mjs +292 -0
  316. package/scripts/test-validate-ia.mjs +262 -0
  317. package/scripts/test-validate-okf.mjs +73 -0
  318. package/scripts/test-validate-page-evidence.mjs +302 -0
  319. package/scripts/test-validate-patterns.mjs +157 -0
  320. package/scripts/test-validate-promotion-rfc.mjs +250 -0
  321. package/scripts/test-validate-reference-profiles.mjs +170 -0
  322. package/scripts/test-validate-unity-org-wiki.mjs +57 -0
  323. package/scripts/test-validate-unity-source-contracts.mjs +67 -0
  324. package/scripts/test-validate-vocabulary.mjs +174 -0
  325. package/scripts/test-validate-webpage-workflow.mjs +293 -0
  326. package/scripts/validate-baseline-manifest.mjs +44 -0
  327. package/scripts/validate-catalog.mjs +65 -0
  328. package/scripts/validate-component-state.mjs +141 -0
  329. package/scripts/validate-consumer-conformance.mjs +477 -0
  330. package/scripts/validate-consumer-reference.mjs +288 -0
  331. package/scripts/validate-domains.mjs +237 -0
  332. package/scripts/validate-governance.mjs +248 -0
  333. package/scripts/validate-ia.mjs +136 -0
  334. package/scripts/validate-links.mjs +66 -0
  335. package/scripts/validate-okf.mjs +104 -0
  336. package/scripts/validate-page-evidence.mjs +191 -0
  337. package/scripts/validate-patterns.mjs +246 -0
  338. package/scripts/validate-promotion-rfc.mjs +224 -0
  339. package/scripts/validate-reference-artifacts.mjs +125 -0
  340. package/scripts/validate-renderer-purity.mjs +56 -0
  341. package/scripts/validate-unity-org-wiki.mjs +146 -0
  342. package/scripts/validate-unity-source-contracts.mjs +107 -0
  343. package/scripts/validate-vocabulary.mjs +115 -0
  344. package/scripts/validate-webpage-workflow.mjs +254 -0
  345. package/scripts/visual-expectation-contract.mjs +20 -0
  346. package/scripts/workflow-action-contract.mjs +163 -0
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ loadKernelModule,
5
+ modulePaths,
6
+ result,
7
+ } from "./test-agent-execution-fixtures.mjs";
8
+ import { exerciseExecutionEffects } from "./test-agent-execution-effects.mjs";
9
+ import { exerciseLearning } from "./test-agent-execution-learning.mjs";
10
+ import { exerciseExecutionLifecycle } from "./test-agent-execution-lifecycle.mjs";
11
+ import { exerciseEvents, exerciseRetrieval } from "./test-agent-execution-views.mjs";
12
+
13
+ async function main() {
14
+ const unknownArgs = process.argv.slice(2).filter((arg) => arg !== "--json");
15
+ if (unknownArgs.length > 0) {
16
+ const report = { ok: false, results: [result("argument_contract", "only --json is accepted", { unknownArgs }, false)] };
17
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
18
+ process.exitCode = 1;
19
+ return;
20
+ }
21
+
22
+ const modules = Object.fromEntries(await Promise.all(Object.keys(modulePaths).map(async (name) => [name, await loadKernelModule(name)])));
23
+ const lifecycle = await exerciseExecutionLifecycle(modules);
24
+ const effects = await exerciseExecutionEffects(modules, lifecycle);
25
+ const state = { ...lifecycle, ...effects };
26
+ const eventRows = await exerciseEvents(modules, state);
27
+ const retrieval = await exerciseRetrieval(modules);
28
+ const learningRows = await exerciseLearning(modules, { ...state, ...retrieval });
29
+ const results = [...lifecycle.rows, ...effects.rows, ...eventRows, ...retrieval.rows, ...learningRows];
30
+ const report = {
31
+ contract: "agent-native-execution-kernel",
32
+ ok: results.length > 0 && results.every((row) => row.ok),
33
+ results,
34
+ };
35
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
36
+ process.exitCode = report.ok ? 0 : 1;
37
+ }
38
+
39
+ await main();
@@ -0,0 +1,130 @@
1
+ import {
2
+ bytes,
3
+ callExport,
4
+ failFromCall,
5
+ fixedNow,
6
+ hasAnyText,
7
+ idOf,
8
+ isObject,
9
+ payload,
10
+ pick,
11
+ result,
12
+ stateOf,
13
+ } from "./test-agent-execution-fixtures.mjs";
14
+
15
+ export async function exerciseLearning(modules, state) {
16
+ const rows = [];
17
+ const proposalInput = {
18
+ claim: { stableRef: "sg:claim/retrieval-improvement", text: "The fixture retriever preserves citation coverage." },
19
+ changes: [{ path: "retriever.strategy", value: "hybrid" }],
20
+ evidence: [{ receiptId: pick(state.receipt, ["receiptId", "receipt_id", "id"]), stableRef: "sg:evidence/execution-fixture" }],
21
+ proposer: "agent:proposer",
22
+ proposalId: "sg:proposal/retrieval-improvement",
23
+ sourceTask: idOf(state.task, "sg:task/execution-fixture"),
24
+ validation: { status: "PASS", validator: "agent:validator", version: "validator@v1" },
25
+ };
26
+ const proposalCall = await callExport(modules.learning, "learning", "createProposal", proposalInput);
27
+ const proposal = proposalCall.ok ? payload(proposalCall.value) : null;
28
+ const directPromotionCall = await callExport(modules.learning, "learning", "promoteProposal", { proposal });
29
+ const directPromotion = directPromotionCall.ok ? payload(directPromotionCall.value) : null;
30
+ rows.push(directPromotionCall.ok
31
+ ? result(
32
+ "promotion_requires_verify_and_decision",
33
+ "proposal cannot promote before an independent verification and accepted governance decision",
34
+ directPromotion,
35
+ !(isObject(directPromotion) && (directPromotion.promoted === true || directPromotion.status === "PROMOTED")),
36
+ )
37
+ : failFromCall("promotion_requires_verify_and_decision", "proposal cannot promote before an independent verification and accepted governance decision", directPromotionCall));
38
+ if (!proposalCall.ok) {
39
+ rows.push(failFromCall("learning_proposal_is_immutable_and_provenanced", "proposal records claim, evidence, validation, proposer, and proposed change", proposalCall));
40
+ return rows;
41
+ }
42
+ rows.push(result(
43
+ "learning_proposal_is_immutable_and_provenanced",
44
+ "proposal records claim, evidence, validation, proposer, and proposed change",
45
+ proposal,
46
+ isObject(proposal)
47
+ && isObject(pick(proposal, ["claim"]))
48
+ && Array.isArray(pick(proposal, ["evidence", "evidenceLinks", "evidence_links"]))
49
+ && isObject(pick(proposal, ["validation"]))
50
+ && typeof pick(proposal, ["proposer", "proposedBy", "proposed_by"]) === "string"
51
+ && Array.isArray(pick(proposal, ["changes", "patch", "delta"])),
52
+ ));
53
+
54
+ const sameActorCall = await callExport(modules.learning, "learning", "verifyProposal", {
55
+ proposal,
56
+ verifier: "agent:proposer",
57
+ verifierActor: "agent:proposer",
58
+ evidence: proposalInput.evidence,
59
+ validation: proposalInput.validation,
60
+ });
61
+ const sameActor = sameActorCall.ok ? payload(sameActorCall.value) : null;
62
+ rows.push(sameActorCall.ok
63
+ ? result(
64
+ "learning_verification_requires_independence",
65
+ "proposer cannot satisfy the independent verification gate",
66
+ sameActor,
67
+ !(isObject(sameActor) && (sameActor.verified === true || sameActor.status === "VERIFIED" || sameActor.ok === true)),
68
+ )
69
+ : failFromCall("learning_verification_requires_independence", "proposer cannot satisfy the independent verification gate", sameActorCall));
70
+
71
+ const verifyCall = await callExport(modules.learning, "learning", "verifyProposal", {
72
+ independentOf: "agent:proposer",
73
+ proposal,
74
+ verifier: "agent:verifier",
75
+ verifierActor: "agent:verifier",
76
+ evidence: [{ ...proposalInput.evidence[0], independentGroup: "verification-group" }],
77
+ validation: { status: "PASS", validator: "agent:validator", version: "validator@v1" },
78
+ });
79
+ const verification = verifyCall.ok ? payload(verifyCall.value) : null;
80
+ rows.push(verifyCall.ok
81
+ ? result(
82
+ "learning_verification_is_independent_and_validated",
83
+ "different actor supplies positive verification with passing validation",
84
+ verification,
85
+ isObject(verification)
86
+ && (pick(verification, ["verified", "isVerified"]) === true || stateOf(verification) === "VERIFIED" || stateOf(verification) === "verified")
87
+ && typeof pick(verification, ["verifier", "verifiedBy", "verified_by"]) === "string"
88
+ && pick(verification, ["verifier", "verifiedBy", "verified_by"]) !== pick(proposal, ["proposer", "proposedBy", "proposed_by"]),
89
+ )
90
+ : failFromCall("learning_verification_is_independent_and_validated", "different actor supplies positive verification with passing validation", verifyCall));
91
+
92
+ const decisionCall = await callExport(modules.learning, "learning", "decideProposal", {
93
+ decision: "ACCEPT",
94
+ governanceDecision: { actor: "governor:test", decision: "ACCEPT", scope: "retriever", decidedAt: fixedNow },
95
+ proposal,
96
+ verification,
97
+ });
98
+ const decision = decisionCall.ok ? payload(decisionCall.value) : null;
99
+ rows.push(decisionCall.ok
100
+ ? result(
101
+ "learning_governance_decision_is_explicit",
102
+ "promotion is gated by an explicit accepted governance decision",
103
+ decision,
104
+ isObject(decision) && hasAnyText(decision, ["decision", "status", "disposition"], ["ACCEPT", "ACCEPTED", "accepted"]),
105
+ )
106
+ : failFromCall("learning_governance_decision_is_explicit", "promotion is gated by an explicit accepted governance decision", decisionCall));
107
+
108
+ const registryBefore = { entries: [{ stableRef: "sg:retriever/fixture", versionId: "sg:retriever/fixture@sha256:4444444444444444444444444444444444444444444444444444444444444444" }] };
109
+ const registryDigestBefore = bytes(registryBefore);
110
+ const promotionCall = await callExport(modules.learning, "learning", "promoteProposal", {
111
+ decision,
112
+ governanceDecision: decision,
113
+ proposal,
114
+ registry: registryBefore,
115
+ verification,
116
+ });
117
+ const promotion = promotionCall.ok ? payload(promotionCall.value) : null;
118
+ rows.push(promotionCall.ok
119
+ ? result(
120
+ "learning_promotion_never_auto_asserts_truth",
121
+ "accepted promotion creates a new governed version/receipt without mutating prior registry or asserting factual truth",
122
+ promotion,
123
+ isObject(promotion)
124
+ && (promotion.promoted === true || hasAnyText(promotion, ["status", "state"], ["PROMOTED", "promoted"]))
125
+ && bytes(registryBefore) === registryDigestBefore
126
+ && pick(promotion, ["autoTruth", "auto_truth", "truthAccepted", "truth_accepted"]) !== true,
127
+ )
128
+ : failFromCall("learning_promotion_never_auto_asserts_truth", "accepted promotion creates a new governed version/receipt without mutating prior registry or asserting factual truth", promotionCall));
129
+ return rows;
130
+ }
@@ -0,0 +1,143 @@
1
+ import {
2
+ callExport,
3
+ failFromCall,
4
+ fixedNow,
5
+ grantInput,
6
+ hasAnyText,
7
+ hasText,
8
+ idOf,
9
+ isObject,
10
+ operationInput,
11
+ payload,
12
+ pick,
13
+ result,
14
+ stateOf,
15
+ } from "./test-agent-execution-fixtures.mjs";
16
+
17
+ export async function exerciseExecutionLifecycle(modules) {
18
+ const rows = [];
19
+ const operationSpec = operationInput();
20
+ const grant = grantInput();
21
+ const operationCall = await callExport(modules.execution, "execution", "defineOperation", operationSpec);
22
+ const operation = operationCall.ok ? payload(operationCall.value) : null;
23
+ rows.push(operationCall.ok
24
+ ? result(
25
+ "operation_spec_defines_effect_and_capability",
26
+ "operation has stable identity, NONE effect, idempotency, and required capability",
27
+ {
28
+ effectClass: pick(operation, ["effectClass", "effect_class", "effect"]),
29
+ idempotent: pick(operation, ["idempotent", "isIdempotent"]),
30
+ requiredCapability: pick(operation, ["requiredCapability", "required_capability", "capability"]),
31
+ stableRef: pick(operation, ["stableRef", "stable_ref", "operation", "name"]),
32
+ },
33
+ isObject(operation)
34
+ && hasAnyText(operation, ["effectClass", "effect_class", "effect"], ["NONE", "none"])
35
+ && pick(operation, ["idempotent", "isIdempotent"]) === true
36
+ && hasText(operation, ["requiredCapability", "required_capability", "capability"], "wiki.read")
37
+ && typeof pick(operation, ["stableRef", "stable_ref", "operation", "name"]) === "string",
38
+ )
39
+ : failFromCall("operation_spec_defines_effect_and_capability", "operation has stable identity, NONE effect, idempotency, and required capability", operationCall));
40
+
41
+ const authorizedCall = await callExport(modules.execution, "execution", "authorizeOperation", {
42
+ capability: grant,
43
+ grant,
44
+ now: fixedNow,
45
+ operation,
46
+ resource: "sg:profile/editorial-reference-profile",
47
+ subject: "agent:test",
48
+ });
49
+ const authorized = authorizedCall.ok ? payload(authorizedCall.value) : null;
50
+ rows.push(authorizedCall.ok
51
+ ? result(
52
+ "capability_authorizes_scoped_read",
53
+ "allowed true with a policy decision bound to subject, operation, resource, and time",
54
+ authorized,
55
+ isObject(authorized)
56
+ && pick(authorized, ["allowed", "isAllowed"]) === true
57
+ && isObject(pick(authorized, ["decision", "policyDecision", "policy_decision"]))
58
+ && typeof pick(pick(authorized, ["decision", "policyDecision", "policy_decision"]), ["subject", "principal"]) === "string",
59
+ )
60
+ : failFromCall("capability_authorizes_scoped_read", "allowed true with a policy decision bound to subject, operation, resource, and time", authorizedCall));
61
+
62
+ const deniedCall = await callExport(modules.execution, "execution", "authorizeOperation", {
63
+ capability: grant,
64
+ grant,
65
+ now: fixedNow,
66
+ operation,
67
+ resource: "sg:governance/private",
68
+ subject: "agent:other",
69
+ });
70
+ const denied = deniedCall.ok ? payload(deniedCall.value) : null;
71
+ rows.push(deniedCall.ok
72
+ ? result(
73
+ "capability_denies_wrong_subject_and_resource",
74
+ "allowed false with a stable authorization failure",
75
+ denied,
76
+ isObject(denied) && pick(denied, ["allowed", "isAllowed"]) === false,
77
+ )
78
+ : failFromCall("capability_denies_wrong_subject_and_resource", "allowed false with a stable authorization failure", deniedCall));
79
+
80
+ const taskInput = {
81
+ intent: { operation: "resolve", resource: "sg:profile/editorial-reference-profile" },
82
+ operation: "resolve",
83
+ requiredResult: { type: "profile" },
84
+ stableRef: "sg:task/execution-fixture",
85
+ taskId: "sg:task/execution-fixture",
86
+ };
87
+ const taskCall = await callExport(modules.execution, "execution", "createTask", taskInput);
88
+ const task = taskCall.ok ? payload(taskCall.value) : null;
89
+ rows.push(taskCall.ok
90
+ ? result(
91
+ "task_preserves_intent_and_required_result",
92
+ "task has stable task identity, intent, required result, and initial state",
93
+ task,
94
+ isObject(task)
95
+ && typeof idOf(task, "sg:task/execution-fixture") === "string"
96
+ && isObject(pick(task, ["intent", "request"]))
97
+ && isObject(pick(task, ["requiredResult", "required_result", "result"]))
98
+ && typeof stateOf(task) === "string",
99
+ )
100
+ : failFromCall("task_preserves_intent_and_required_result", "task has stable task identity, intent, required result, and initial state", taskCall));
101
+
102
+ const runCall = await callExport(modules.execution, "execution", "startRun", {
103
+ input: { stableRef: "sg:profile/editorial-reference-profile" },
104
+ runId: "sg:run/execution-fixture-1",
105
+ run_id: "sg:run/execution-fixture-1",
106
+ task,
107
+ taskId: pick(task, ["taskId", "task_id", "stableRef", "stable_ref"]) ?? "sg:task/execution-fixture",
108
+ });
109
+ const run = runCall.ok ? payload(runCall.value) : null;
110
+ rows.push(runCall.ok
111
+ ? result(
112
+ "run_belongs_to_one_task",
113
+ "run has a distinct run identity linked to the task",
114
+ run,
115
+ isObject(run)
116
+ && pick(run, ["runId", "run_id", "stableRef", "stable_ref", "id"]) === "sg:run/execution-fixture-1"
117
+ && pick(run, ["taskId", "task_id"]) === (pick(task, ["taskId", "task_id", "stableRef", "stable_ref"]) ?? "sg:task/execution-fixture")
118
+ && typeof stateOf(run) === "string",
119
+ )
120
+ : failFromCall("run_belongs_to_one_task", "run has a distinct run identity linked to the task", runCall));
121
+
122
+ const immediateAuthCall = await callExport(modules.execution, "execution", "authorizeEffect", {
123
+ capability: grant,
124
+ grant,
125
+ now: fixedNow,
126
+ operation,
127
+ resource: "sg:profile/editorial-reference-profile",
128
+ run,
129
+ subject: "agent:test",
130
+ task,
131
+ });
132
+ const immediateAuth = immediateAuthCall.ok ? payload(immediateAuthCall.value) : null;
133
+ rows.push(immediateAuthCall.ok
134
+ ? result(
135
+ "effect_rechecks_authorization_immediately",
136
+ "effect authorization is explicitly allowed immediately before an external attempt",
137
+ immediateAuth,
138
+ isObject(immediateAuth) && pick(immediateAuth, ["allowed", "isAllowed"]) === true,
139
+ )
140
+ : failFromCall("effect_rechecks_authorization_immediately", "effect authorization is explicitly allowed immediately before an external attempt", immediateAuthCall));
141
+
142
+ return { rows, operation, grant, task, run, authorized };
143
+ }
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ authorizeOperation,
5
+ defineOperation,
6
+ reconcileEffect,
7
+ recordEffectAttempt,
8
+ } from "./agent-native/execution.mjs";
9
+
10
+ const cases = [];
11
+
12
+ function test(name, scenario) {
13
+ try {
14
+ scenario();
15
+ cases.push({ name, ok: true });
16
+ } catch (error) {
17
+ cases.push({
18
+ error: error instanceof Error ? error.message : String(error),
19
+ name,
20
+ ok: false,
21
+ });
22
+ }
23
+ }
24
+
25
+ function equal(actual, expected, label) {
26
+ if (actual !== expected) throw new Error(`${label}: expected ${expected}, received ${actual}`);
27
+ }
28
+
29
+ function operation() {
30
+ return defineOperation({
31
+ effect_class: "EXTERNAL",
32
+ name: "publish",
33
+ required_capability: "wiki.publish",
34
+ stable_ref: "sg:operation/publish",
35
+ });
36
+ }
37
+
38
+ function grant(operations) {
39
+ return {
40
+ capability: "wiki.publish",
41
+ operations,
42
+ resource_scope: ["sg:profile/*"],
43
+ subject: "agent:test",
44
+ };
45
+ }
46
+
47
+ function authorization(operations) {
48
+ return authorizeOperation({
49
+ grant: grant(operations),
50
+ operation: operation(),
51
+ resource: "sg:profile/editorial-reference-profile",
52
+ subject: "agent:test",
53
+ });
54
+ }
55
+
56
+ function externalEffect(overrides = {}) {
57
+ return recordEffectAttempt({
58
+ effect_class: "EXTERNAL",
59
+ effect_id: "sg:effect/publish-1",
60
+ run_id: "sg:run/publish-1",
61
+ task_id: "sg:task/publish-1",
62
+ ...overrides,
63
+ });
64
+ }
65
+
66
+ test("empty_operation_scope_denies_protected_operation", () => {
67
+ // Given a capability with matching subject, resource, and capability but no operations.
68
+ // When authorization evaluates the protected publish operation.
69
+ const result = authorization([]);
70
+ // Then omission is deny-by-default rather than a wildcard grant.
71
+ equal(result.allowed, false, "allowed");
72
+ equal(result.failures.includes("operation_denied"), true, "operation_denied");
73
+ });
74
+
75
+ test("explicit_operation_scope_authorizes_matching_operation", () => {
76
+ // Given an explicitly scoped capability.
77
+ // When the named operation is evaluated.
78
+ const result = authorization(["publish"]);
79
+ // Then the operation is authorized.
80
+ equal(result.allowed, true, "allowed");
81
+ });
82
+
83
+ test("external_effect_ignores_forged_committed_state_without_receipt", () => {
84
+ // Given an external attempt with no connector receipt and caller state COMMITTED.
85
+ // When the attempt is recorded.
86
+ const effect = externalEffect({ connector_receipt: null, state: "COMMITTED" });
87
+ // Then the kernel derives UNCERTAIN.
88
+ equal(effect.state, "UNCERTAIN", "state");
89
+ });
90
+
91
+ test("empty_connector_receipt_cannot_commit_external_effect", () => {
92
+ // Given an external attempt with an empty receipt identifier.
93
+ // When the caller requests COMMITTED.
94
+ const effect = externalEffect({ connector_receipt: "", state: "COMMITTED" });
95
+ // Then empty evidence is treated as absent.
96
+ equal(effect.state, "UNCERTAIN", "state");
97
+ });
98
+
99
+ test("blank_connector_receipt_cannot_commit_external_effect", () => {
100
+ // Given an external attempt with only whitespace as receipt evidence.
101
+ // When the caller requests COMMITTED.
102
+ const effect = externalEffect({ connector_receipt: " ", state: "COMMITTED" });
103
+ // Then blank evidence is treated as absent.
104
+ equal(effect.state, "UNCERTAIN", "state");
105
+ });
106
+
107
+ test("durable_receipt_commits_external_effect", () => {
108
+ // Given an external attempt backed by a durable connector receipt ID.
109
+ // When the caller supplies a conflicting state.
110
+ const effect = externalEffect({ connector_receipt: "sg:connector-receipt/publish-1", state: "UNCERTAIN" });
111
+ // Then receipt evidence, not caller state, derives COMMITTED.
112
+ equal(effect.state, "COMMITTED", "state");
113
+ });
114
+
115
+ test("positive_observation_without_receipt_stays_uncertain", () => {
116
+ // Given an uncertain external effect and an unreceipted positive observation.
117
+ // When reconciliation runs.
118
+ const reconciled = reconcileEffect({
119
+ effect: externalEffect(),
120
+ observations: [{ status: "COMMITTED" }],
121
+ });
122
+ // Then status alone cannot commit the effect.
123
+ equal(reconciled.state, "UNCERTAIN", "state");
124
+ });
125
+
126
+ test("positive_receipted_observation_commits", () => {
127
+ // Given an uncertain effect and a positive durable receipt observation.
128
+ // When reconciliation runs.
129
+ const reconciled = reconcileEffect({
130
+ effect: externalEffect(),
131
+ observations: [{ connector_receipt: "sg:connector-receipt/recovered", status: "COMMITTED" }],
132
+ });
133
+ // Then the effect is committed and bound to that receipt.
134
+ equal(reconciled.state, "COMMITTED", "state");
135
+ equal(reconciled.connector_receipt, "sg:connector-receipt/recovered", "connector_receipt");
136
+ });
137
+
138
+ test("legacy_unreceipted_committed_effect_is_demoted", () => {
139
+ // Given legacy data claiming COMMITTED without receipt evidence.
140
+ // When it is reconciled without new observations.
141
+ const reconciled = reconcileEffect({
142
+ effect: {
143
+ effect_class: "EXTERNAL",
144
+ effect_id: "sg:effect/legacy",
145
+ state: "COMMITTED",
146
+ },
147
+ });
148
+ // Then reconciliation restores the safe UNCERTAIN state.
149
+ equal(reconciled.state, "UNCERTAIN", "state");
150
+ });
151
+
152
+ const report = {
153
+ contract: "agent-native-execution-safety",
154
+ ok: cases.every((item) => item.ok),
155
+ results: cases,
156
+ };
157
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
158
+ process.exitCode = report.ok ? 0 : 1;
@@ -0,0 +1,117 @@
1
+ import {
2
+ bytes,
3
+ callExport,
4
+ failFromCall,
5
+ fixedNow,
6
+ idOf,
7
+ isObject,
8
+ payload,
9
+ pick,
10
+ result,
11
+ } from "./test-agent-execution-fixtures.mjs";
12
+
13
+ export async function exerciseEvents(modules, state) {
14
+ const rows = [];
15
+ let events = [];
16
+ const entries = [
17
+ { eventId: "sg:event/task-created", parents: [], payload: { taskId: idOf(state.task, "sg:task/execution-fixture") }, type: "task.created" },
18
+ { eventId: "sg:event/run-started", parents: ["sg:event/task-created"], payload: { runId: idOf(state.run, "sg:run/execution-fixture-1") }, type: "run.started" },
19
+ { eventId: "sg:event/effect-reconciled", parents: ["sg:event/task-created"], payload: { effectState: "COMMITTED" }, type: "effect.reconciled" },
20
+ ];
21
+ for (const event of entries) {
22
+ const call = await callExport(modules.events, "events", "appendEvent", { event, events });
23
+ if (!call.ok) {
24
+ rows.push(failFromCall("event_dag_append_is_immutable", "appendEvent returns an append-only event collection", call));
25
+ return rows;
26
+ }
27
+ const value = payload(call.value);
28
+ if (Array.isArray(value)) events = value;
29
+ else if (Array.isArray(value?.events)) events = value.events;
30
+ else if (isObject(value?.event)) events = [...events, value.event];
31
+ else if (isObject(value)) events = [...events, value];
32
+ else events = [...events, event];
33
+ }
34
+ const appendResult = events.map((event) => ({ id: pick(event, ["eventId", "event_id", "id", "stableRef", "stable_ref"]), parents: pick(event, ["parents", "parentIds", "parent_ids"]) }));
35
+ rows.push(result(
36
+ "event_dag_append_is_immutable",
37
+ "three immutable events preserve explicit parent links and event IDs",
38
+ appendResult,
39
+ events.length === 3
40
+ && appendResult.every((event) => typeof event.id === "string" && Array.isArray(event.parents))
41
+ && appendResult[1].parents.includes("sg:event/task-created")
42
+ && appendResult[2].parents.includes("sg:event/task-created"),
43
+ ));
44
+
45
+ const headsCall = await callExport(modules.events, "events", "eventHeads", { events });
46
+ if (!headsCall.ok) {
47
+ rows.push(failFromCall("event_dag_heads_are_deterministic", "eventHeads returns the two concurrent heads in stable order", headsCall));
48
+ return rows;
49
+ }
50
+ const heads = payload(headsCall.value);
51
+ const headValues = Array.isArray(heads) ? heads : pick(heads, ["heads", "eventHeads", "event_heads"]);
52
+ rows.push(result(
53
+ "event_dag_heads_are_deterministic",
54
+ "eventHeads returns the two concurrent heads in stable order",
55
+ headValues,
56
+ Array.isArray(headValues)
57
+ && headValues.length === 2
58
+ && headValues.map(String).sort().join(",") === "sg:event/effect-reconciled,sg:event/run-started",
59
+ ));
60
+ return rows;
61
+ }
62
+
63
+ export async function exerciseRetrieval(modules) {
64
+ const rows = [];
65
+ const members = [
66
+ { content: "Editorial profile uses constrained columns.", stableRef: "sg:profile/editorial-reference-profile", versionId: "sg:profile/editorial-reference-profile@sha256:1111111111111111111111111111111111111111111111111111111111111111" },
67
+ { content: "Resolve returns governed profile metadata.", stableRef: "sg:claim/resolve-profile", versionId: "sg:claim/resolve-profile@sha256:2222222222222222222222222222222222222222222222222222222222222222" },
68
+ ];
69
+ const snapshotInput = {
70
+ asOf: fixedNow,
71
+ builderVersion: "retriever-fixture@1",
72
+ heads: ["sg:event/effect-reconciled", "sg:event/run-started"],
73
+ members,
74
+ policy: "sg:governance/read-policy@sha256:3333333333333333333333333333333333333333333333333333333333333333",
75
+ viewSpec: { queryClass: "exact", stableRef: "sg:view/profile-context", version: "v1" },
76
+ };
77
+ const snapshotCallA = await callExport(modules.retrieval, "retrieval", "buildViewSnapshot", snapshotInput);
78
+ const snapshotCallB = await callExport(modules.retrieval, "retrieval", "buildViewSnapshot", { ...snapshotInput, members: [...members].reverse(), heads: [...snapshotInput.heads].reverse() });
79
+ const snapshotA = snapshotCallA.ok ? payload(snapshotCallA.value) : null;
80
+ const snapshotB = snapshotCallB.ok ? payload(snapshotCallB.value) : null;
81
+ if (!snapshotCallA.ok) rows.push(failFromCall("retrieval_snapshot_is_deterministic", "same inputs produce byte-identical snapshot", snapshotCallA));
82
+ else if (!snapshotCallB.ok) rows.push(failFromCall("retrieval_snapshot_is_deterministic", "same inputs produce byte-identical snapshot", snapshotCallB));
83
+ else rows.push(result(
84
+ "retrieval_snapshot_is_deterministic",
85
+ "same logical inputs produce byte-identical immutable snapshot with provenance",
86
+ { first: snapshotA, second: snapshotB, equal: bytes(snapshotA) === bytes(snapshotB) },
87
+ bytes(snapshotA) === bytes(snapshotB)
88
+ && isObject(snapshotA)
89
+ && typeof pick(snapshotA, ["versionId", "version_id", "snapshotRef", "snapshot_ref", "digest", "sha256"]) === "string"
90
+ && Array.isArray(pick(snapshotA, ["members", "entries", "items"])),
91
+ ));
92
+
93
+ const contextCall = await callExport(modules.retrieval, "retrieval", "buildContextPackage", {
94
+ budget: { tokens: 240 },
95
+ members,
96
+ policy: snapshotInput.policy,
97
+ queryClass: "exact",
98
+ query: "Which profile is editorial?",
99
+ retriever: "retriever:fixture@v1",
100
+ snapshot: snapshotA,
101
+ });
102
+ const context = contextCall.ok ? payload(contextCall.value) : null;
103
+ rows.push(contextCall.ok
104
+ ? result(
105
+ "context_package_is_bounded_and_provenance_linked",
106
+ "context package preserves snapshot/policy/member manifest and token budget",
107
+ context,
108
+ isObject(context)
109
+ && isObject(pick(context, ["budget"]))
110
+ && Number.isInteger(pick(pick(context, ["budget"]), ["tokens", "tokenBudget", "token_budget"]))
111
+ && Array.isArray(pick(context, ["members", "entries", "items"]))
112
+ && pick(context, ["snapshot", "snapshotRef", "snapshot_ref"]) !== undefined
113
+ && pick(context, ["policy", "policyRef", "policy_ref"]) !== undefined,
114
+ )
115
+ : failFromCall("context_package_is_bounded_and_provenance_linked", "context package preserves snapshot/policy/member manifest and token budget", contextCall));
116
+ return { rows, snapshot: snapshotA, context };
117
+ }