@empressaio/atom-contract 1.7.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 (251) hide show
  1. package/CHANGELOG.md +360 -0
  2. package/README.md +379 -0
  3. package/dist/composition.d.ts +112 -0
  4. package/dist/composition.d.ts.map +1 -0
  5. package/dist/composition.js +80 -0
  6. package/dist/composition.js.map +1 -0
  7. package/dist/conformance/common.d.ts +21 -0
  8. package/dist/conformance/common.d.ts.map +1 -0
  9. package/dist/conformance/common.js +29 -0
  10. package/dist/conformance/common.js.map +1 -0
  11. package/dist/conformance/fixtures.d.ts +13 -0
  12. package/dist/conformance/fixtures.d.ts.map +1 -0
  13. package/dist/conformance/fixtures.js +63 -0
  14. package/dist/conformance/fixtures.js.map +1 -0
  15. package/dist/conformance/index.d.ts +11 -0
  16. package/dist/conformance/index.d.ts.map +1 -0
  17. package/dist/conformance/index.js +11 -0
  18. package/dist/conformance/index.js.map +1 -0
  19. package/dist/conformance/validate.d.ts +49 -0
  20. package/dist/conformance/validate.d.ts.map +1 -0
  21. package/dist/conformance/validate.js +138 -0
  22. package/dist/conformance/validate.js.map +1 -0
  23. package/dist/conformance/verify-chain.d.ts +25 -0
  24. package/dist/conformance/verify-chain.d.ts.map +1 -0
  25. package/dist/conformance/verify-chain.js +76 -0
  26. package/dist/conformance/verify-chain.js.map +1 -0
  27. package/dist/context.d.ts +134 -0
  28. package/dist/context.d.ts.map +1 -0
  29. package/dist/context.js +110 -0
  30. package/dist/context.js.map +1 -0
  31. package/dist/encumbrances/administrative-rule.d.ts +128 -0
  32. package/dist/encumbrances/administrative-rule.d.ts.map +1 -0
  33. package/dist/encumbrances/administrative-rule.js +18 -0
  34. package/dist/encumbrances/administrative-rule.js.map +1 -0
  35. package/dist/encumbrances/common.d.ts +153 -0
  36. package/dist/encumbrances/common.d.ts.map +1 -0
  37. package/dist/encumbrances/common.js +124 -0
  38. package/dist/encumbrances/common.js.map +1 -0
  39. package/dist/encumbrances/constraint-resolution.d.ts +169 -0
  40. package/dist/encumbrances/constraint-resolution.d.ts.map +1 -0
  41. package/dist/encumbrances/constraint-resolution.js +41 -0
  42. package/dist/encumbrances/constraint-resolution.js.map +1 -0
  43. package/dist/encumbrances/fixtures.d.ts +16 -0
  44. package/dist/encumbrances/fixtures.d.ts.map +1 -0
  45. package/dist/encumbrances/fixtures.js +107 -0
  46. package/dist/encumbrances/fixtures.js.map +1 -0
  47. package/dist/encumbrances/index.d.ts +15 -0
  48. package/dist/encumbrances/index.d.ts.map +1 -0
  49. package/dist/encumbrances/index.js +15 -0
  50. package/dist/encumbrances/index.js.map +1 -0
  51. package/dist/encumbrances/recorded-instrument.d.ts +131 -0
  52. package/dist/encumbrances/recorded-instrument.d.ts.map +1 -0
  53. package/dist/encumbrances/recorded-instrument.js +19 -0
  54. package/dist/encumbrances/recorded-instrument.js.map +1 -0
  55. package/dist/encumbrances/restriction-clause.d.ts +120 -0
  56. package/dist/encumbrances/restriction-clause.d.ts.map +1 -0
  57. package/dist/encumbrances/restriction-clause.js +17 -0
  58. package/dist/encumbrances/restriction-clause.js.map +1 -0
  59. package/dist/encumbrances/restriction-corpus.d.ts +44 -0
  60. package/dist/encumbrances/restriction-corpus.d.ts.map +1 -0
  61. package/dist/encumbrances/restriction-corpus.js +14 -0
  62. package/dist/encumbrances/restriction-corpus.js.map +1 -0
  63. package/dist/export/downloadable-atom.d.ts +133 -0
  64. package/dist/export/downloadable-atom.d.ts.map +1 -0
  65. package/dist/export/downloadable-atom.js +115 -0
  66. package/dist/export/downloadable-atom.js.map +1 -0
  67. package/dist/export/index.d.ts +6 -0
  68. package/dist/export/index.d.ts.map +1 -0
  69. package/dist/export/index.js +6 -0
  70. package/dist/export/index.js.map +1 -0
  71. package/dist/history.d.ts +124 -0
  72. package/dist/history.d.ts.map +1 -0
  73. package/dist/history.js +170 -0
  74. package/dist/history.js.map +1 -0
  75. package/dist/index.d.ts +29 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +20 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/inline-reference.d.ts +60 -0
  80. package/dist/inline-reference.d.ts.map +1 -0
  81. package/dist/inline-reference.js +73 -0
  82. package/dist/inline-reference.js.map +1 -0
  83. package/dist/obligation.d.ts +131 -0
  84. package/dist/obligation.d.ts.map +1 -0
  85. package/dist/obligation.js +55 -0
  86. package/dist/obligation.js.map +1 -0
  87. package/dist/og/common.d.ts +253 -0
  88. package/dist/og/common.d.ts.map +1 -0
  89. package/dist/og/common.js +195 -0
  90. package/dist/og/common.js.map +1 -0
  91. package/dist/og/completion.d.ts +70 -0
  92. package/dist/og/completion.d.ts.map +1 -0
  93. package/dist/og/completion.js +22 -0
  94. package/dist/og/completion.js.map +1 -0
  95. package/dist/og/equipment-state.d.ts +55 -0
  96. package/dist/og/equipment-state.d.ts.map +1 -0
  97. package/dist/og/equipment-state.js +25 -0
  98. package/dist/og/equipment-state.js.map +1 -0
  99. package/dist/og/fixtures.d.ts +40 -0
  100. package/dist/og/fixtures.d.ts.map +1 -0
  101. package/dist/og/fixtures.js +255 -0
  102. package/dist/og/fixtures.js.map +1 -0
  103. package/dist/og/index.d.ts +23 -0
  104. package/dist/og/index.d.ts.map +1 -0
  105. package/dist/og/index.js +23 -0
  106. package/dist/og/index.js.map +1 -0
  107. package/dist/og/mineral-lease.d.ts +150 -0
  108. package/dist/og/mineral-lease.d.ts.map +1 -0
  109. package/dist/og/mineral-lease.js +24 -0
  110. package/dist/og/mineral-lease.js.map +1 -0
  111. package/dist/og/ownership-interest.d.ts +163 -0
  112. package/dist/og/ownership-interest.d.ts.map +1 -0
  113. package/dist/og/ownership-interest.js +36 -0
  114. package/dist/og/ownership-interest.js.map +1 -0
  115. package/dist/og/pad.d.ts +101 -0
  116. package/dist/og/pad.d.ts.map +1 -0
  117. package/dist/og/pad.js +19 -0
  118. package/dist/og/pad.js.map +1 -0
  119. package/dist/og/production-timeseries.d.ts +154 -0
  120. package/dist/og/production-timeseries.d.ts.map +1 -0
  121. package/dist/og/production-timeseries.js +37 -0
  122. package/dist/og/production-timeseries.js.map +1 -0
  123. package/dist/og/revenue-allocation-unit.d.ts +762 -0
  124. package/dist/og/revenue-allocation-unit.d.ts.map +1 -0
  125. package/dist/og/revenue-allocation-unit.js +105 -0
  126. package/dist/og/revenue-allocation-unit.js.map +1 -0
  127. package/dist/og/rrc-lease.d.ts +124 -0
  128. package/dist/og/rrc-lease.d.ts.map +1 -0
  129. package/dist/og/rrc-lease.js +29 -0
  130. package/dist/og/rrc-lease.js.map +1 -0
  131. package/dist/og/tract.d.ts +88 -0
  132. package/dist/og/tract.d.ts.map +1 -0
  133. package/dist/og/tract.js +30 -0
  134. package/dist/og/tract.js.map +1 -0
  135. package/dist/og/well.d.ts +201 -0
  136. package/dist/og/well.d.ts.map +1 -0
  137. package/dist/og/well.js +40 -0
  138. package/dist/og/well.js.map +1 -0
  139. package/dist/og/wellbore.d.ts +61 -0
  140. package/dist/og/wellbore.d.ts.map +1 -0
  141. package/dist/og/wellbore.js +25 -0
  142. package/dist/og/wellbore.js.map +1 -0
  143. package/dist/og/zone.d.ts +45 -0
  144. package/dist/og/zone.d.ts.map +1 -0
  145. package/dist/og/zone.js +16 -0
  146. package/dist/og/zone.js.map +1 -0
  147. package/dist/read-contract/common.d.ts +74 -0
  148. package/dist/read-contract/common.d.ts.map +1 -0
  149. package/dist/read-contract/common.js +54 -0
  150. package/dist/read-contract/common.js.map +1 -0
  151. package/dist/read-contract/consequence.d.ts +99 -0
  152. package/dist/read-contract/consequence.d.ts.map +1 -0
  153. package/dist/read-contract/consequence.js +46 -0
  154. package/dist/read-contract/consequence.js.map +1 -0
  155. package/dist/read-contract/fixtures.d.ts +8 -0
  156. package/dist/read-contract/fixtures.d.ts.map +1 -0
  157. package/dist/read-contract/fixtures.js +44 -0
  158. package/dist/read-contract/fixtures.js.map +1 -0
  159. package/dist/read-contract/index.d.ts +14 -0
  160. package/dist/read-contract/index.d.ts.map +1 -0
  161. package/dist/read-contract/index.js +14 -0
  162. package/dist/read-contract/index.js.map +1 -0
  163. package/dist/read-contract/model-attribution.d.ts +85 -0
  164. package/dist/read-contract/model-attribution.d.ts.map +1 -0
  165. package/dist/read-contract/model-attribution.js +30 -0
  166. package/dist/read-contract/model-attribution.js.map +1 -0
  167. package/dist/read-contract/read-contract.d.ts +455 -0
  168. package/dist/read-contract/read-contract.d.ts.map +1 -0
  169. package/dist/read-contract/read-contract.js +46 -0
  170. package/dist/read-contract/read-contract.js.map +1 -0
  171. package/dist/registration.d.ts +192 -0
  172. package/dist/registration.d.ts.map +1 -0
  173. package/dist/registration.js +15 -0
  174. package/dist/registration.js.map +1 -0
  175. package/dist/registry.d.ts +128 -0
  176. package/dist/registry.d.ts.map +1 -0
  177. package/dist/registry.js +122 -0
  178. package/dist/registry.js.map +1 -0
  179. package/dist/render.d.ts +30 -0
  180. package/dist/render.d.ts.map +1 -0
  181. package/dist/render.js +44 -0
  182. package/dist/render.js.map +1 -0
  183. package/dist/scope.d.ts +46 -0
  184. package/dist/scope.d.ts.map +1 -0
  185. package/dist/scope.js +17 -0
  186. package/dist/scope.js.map +1 -0
  187. package/dist/temporal/anticipatory-atom.d.ts +123 -0
  188. package/dist/temporal/anticipatory-atom.d.ts.map +1 -0
  189. package/dist/temporal/anticipatory-atom.js +124 -0
  190. package/dist/temporal/anticipatory-atom.js.map +1 -0
  191. package/dist/temporal/common.d.ts +47 -0
  192. package/dist/temporal/common.d.ts.map +1 -0
  193. package/dist/temporal/common.js +100 -0
  194. package/dist/temporal/common.js.map +1 -0
  195. package/dist/temporal/fixtures.d.ts +7 -0
  196. package/dist/temporal/fixtures.d.ts.map +1 -0
  197. package/dist/temporal/fixtures.js +21 -0
  198. package/dist/temporal/fixtures.js.map +1 -0
  199. package/dist/temporal/index.d.ts +13 -0
  200. package/dist/temporal/index.d.ts.map +1 -0
  201. package/dist/temporal/index.js +13 -0
  202. package/dist/temporal/index.js.map +1 -0
  203. package/dist/temporal/interval-query.d.ts +42 -0
  204. package/dist/temporal/interval-query.d.ts.map +1 -0
  205. package/dist/temporal/interval-query.js +49 -0
  206. package/dist/temporal/interval-query.js.map +1 -0
  207. package/dist/temporal/node-id.d.ts +112 -0
  208. package/dist/temporal/node-id.d.ts.map +1 -0
  209. package/dist/temporal/node-id.js +208 -0
  210. package/dist/temporal/node-id.js.map +1 -0
  211. package/dist/temporal/would-affect-edge.d.ts +66 -0
  212. package/dist/temporal/would-affect-edge.d.ts.map +1 -0
  213. package/dist/temporal/would-affect-edge.js +113 -0
  214. package/dist/temporal/would-affect-edge.js.map +1 -0
  215. package/dist/testing/index.d.ts +98 -0
  216. package/dist/testing/index.d.ts.map +1 -0
  217. package/dist/testing/index.js +225 -0
  218. package/dist/testing/index.js.map +1 -0
  219. package/dist/vda.d.ts +46 -0
  220. package/dist/vda.d.ts.map +1 -0
  221. package/dist/vda.js +42 -0
  222. package/dist/vda.js.map +1 -0
  223. package/dist/workspace/brief-run.d.ts +104 -0
  224. package/dist/workspace/brief-run.d.ts.map +1 -0
  225. package/dist/workspace/brief-run.js +32 -0
  226. package/dist/workspace/brief-run.js.map +1 -0
  227. package/dist/workspace/common.d.ts +42 -0
  228. package/dist/workspace/common.d.ts.map +1 -0
  229. package/dist/workspace/common.js +26 -0
  230. package/dist/workspace/common.js.map +1 -0
  231. package/dist/workspace/fixtures.d.ts +10 -0
  232. package/dist/workspace/fixtures.d.ts.map +1 -0
  233. package/dist/workspace/fixtures.js +93 -0
  234. package/dist/workspace/fixtures.js.map +1 -0
  235. package/dist/workspace/index.d.ts +13 -0
  236. package/dist/workspace/index.d.ts.map +1 -0
  237. package/dist/workspace/index.js +13 -0
  238. package/dist/workspace/index.js.map +1 -0
  239. package/dist/workspace/property-workspace.d.ts +148 -0
  240. package/dist/workspace/property-workspace.d.ts.map +1 -0
  241. package/dist/workspace/property-workspace.js +21 -0
  242. package/dist/workspace/property-workspace.js.map +1 -0
  243. package/dist/workspace/workspace-attachment.d.ts +99 -0
  244. package/dist/workspace/workspace-attachment.d.ts.map +1 -0
  245. package/dist/workspace/workspace-attachment.js +35 -0
  246. package/dist/workspace/workspace-attachment.js.map +1 -0
  247. package/dist/workspace/workspace-share-edge.d.ts +115 -0
  248. package/dist/workspace/workspace-share-edge.d.ts.map +1 -0
  249. package/dist/workspace/workspace-share-edge.js +22 -0
  250. package/dist/workspace/workspace-share-edge.js.map +1 -0
  251. package/package.json +107 -0
package/README.md ADDED
@@ -0,0 +1,379 @@
1
+ # `@empressaio/atom-contract`
2
+
3
+ The typed-data substrate every Empressa atom must satisfy: identity,
4
+ context interface, composition declaration, and history anchoring.
5
+ Peer to the Hauska SDK (`@hauska-sdk/*`); consumed directly by every product surface
6
+ and MCP server.
7
+
8
+ This package is **framework only**. It ships the contract, the runtime
9
+ that enforces it, the schema the history layer writes into, and the
10
+ test scaffolding consumer packages use to prove their atoms comply.
11
+ Catalog atom registrations (the actual atom types — `engagement`,
12
+ `code-section`, `jurisdiction-corpus`, etc.) live in consumer packages
13
+ that depend on this one.
14
+
15
+ Empressa commercial substrate, peer to `@hauska-sdk/*` and `hauska-engine`,
16
+ per doc_repo ADR-018 (atom contract substrate layer placement). The
17
+ package has zero `@hauska-sdk/*` dependency: an MCP server or product
18
+ surface can depend on the contract without inheriting the commerce
19
+ stack.
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ npm install @empressaio/atom-contract
25
+ # or
26
+ pnpm add @empressaio/atom-contract
27
+ ```
28
+
29
+ Requires Node 18.18+ and `drizzle-orm` (^0.30.0) if you intend to use
30
+ `PostgresEventAnchoringService`. Atoms that don't anchor history can
31
+ use `createInMemoryEventService()` from the `./testing` subpath.
32
+
33
+ ## Publishing (operators)
34
+
35
+ The `hauska-sdk` npm account uses **staged publishing + Windows Hello**
36
+ (passkey 2FA), not granular tokens. See
37
+ [`docs/npm-publish-automation.md`](docs/npm-publish-automation.md).
38
+
39
+ ```powershell
40
+ .\publish-1.4.0.ps1
41
+ .\publish-approve-1.4.0.ps1 -StageId <uuid-from-stage-list>
42
+ ```
43
+
44
+ ## Public surface
45
+
46
+ ```ts
47
+ import {
48
+ createAtomRegistry,
49
+ defaultScope,
50
+ resolveMode,
51
+ parseInlineReferences,
52
+ serializeInlineReference,
53
+ httpContextSummary,
54
+ resolveComposition,
55
+ PostgresEventAnchoringService,
56
+ wrapForStorage,
57
+ unwrapFromStorage,
58
+ type AccessPolicy,
59
+ type AtomRegistration,
60
+ type AtomMode,
61
+ type AtomReference,
62
+ type ContextSummary,
63
+ type Scope,
64
+ type AtomComposition,
65
+ type EventAnchoringService,
66
+ } from "@empressaio/atom-contract";
67
+ ```
68
+
69
+ Testing utilities live behind a separate subpath so production bundles
70
+ never pull them in:
71
+
72
+ ```ts
73
+ import {
74
+ createTestRegistry,
75
+ createInMemoryEventService,
76
+ runAtomContractTests,
77
+ } from "@empressaio/atom-contract/testing";
78
+ ```
79
+
80
+ ## The four-layer contract
81
+
82
+ An atom registers with one structurally-typed object:
83
+
84
+ ```ts
85
+ const taskAtom: AtomRegistration<"task", ["card", "compact", "expanded"]> = {
86
+ // identity
87
+ entityType: "task",
88
+ domain: "sprint",
89
+
90
+ // render-mode contract (type-level)
91
+ supportedModes: ["card", "compact", "expanded"],
92
+ defaultMode: "card",
93
+
94
+ // context interface
95
+ contextSummary: async (entityId, scope) => ({
96
+ prose: `Task ${entityId}: ...`,
97
+ typed: { id: entityId },
98
+ keyMetrics: [{ label: "Status", value: "open" }],
99
+ relatedAtoms: [],
100
+ historyProvenance: { latestEventId: "evt-...", latestEventAt: "2026-..." },
101
+ scopeFiltered: false,
102
+ }),
103
+
104
+ // composition declaration (multi-child; required field)
105
+ composition: [
106
+ { childEntityType: "blocker", childMode: "compact", dataKey: "blockers" },
107
+ ],
108
+ };
109
+
110
+ const registry = createAtomRegistry();
111
+ registry.register(taskAtom);
112
+ ```
113
+
114
+ Compile-time guarantees:
115
+
116
+ - `defaultMode` must be a member of `supportedModes`. Mismatched defaults
117
+ fail to typecheck.
118
+ - `entityType` is a literal string, narrowed all the way through
119
+ `registry.resolve("task")` so consumers see the exact type back.
120
+ - `domain` is required and queryable through `registry.listByDomain(...)`.
121
+ - `composition` is required. Pass `[]` to declare no children.
122
+
123
+ Five render modes ship as a literal union: `inline`, `compact`, `card`,
124
+ `expanded`, `focus`. Render bindings (the React `<AtomShell>`, per-mode
125
+ components, focus-store wiring) live in a separate package that
126
+ depends on this one.
127
+
128
+ ## Scope at the call site
129
+
130
+ `contextSummary` always takes a second `Scope` argument:
131
+
132
+ ```ts
133
+ interface Scope {
134
+ audience: "ai" | "user" | "internal";
135
+ requestor?: { kind: "user" | "agent"; id: string };
136
+ asOf?: Date;
137
+ permissions?: ReadonlyArray<string>;
138
+ }
139
+ ```
140
+
141
+ Atoms that don't differentiate by scope ignore it and set
142
+ `scopeFiltered: false`. Tests use the `defaultScope()` helper.
143
+
144
+ ## Composition
145
+
146
+ Composition is a multi-child declarative graph. The registry consumes
147
+ the field: `registry.validate()` walks every registration's composition
148
+ edges and reports any that point at an unregistered child entity type.
149
+ Use `resolveComposition(parent, parentRef, parentData, registry)` to
150
+ turn the declaration into a typed children list ready for render-side
151
+ iteration.
152
+
153
+ **Boot-time contract:** the application bootstrap MUST call
154
+ `registry.validate()` once after every `register()` call has run and
155
+ fail to start when the result is `{ ok: false }`. The registry does
156
+ not revalidate composition on each `register()` (the parent may
157
+ legitimately register before the child) and `resolve()` does not
158
+ recheck on lookup, so dangling cross-references would otherwise
159
+ surface only at composition-resolution time.
160
+
161
+ Composition edges may opt out of presence validation by setting
162
+ `forwardRef: true`. Forward-ref edges are skipped by both `validate()`
163
+ and `resolveComposition` while the child remains unregistered, so a
164
+ parent atom can ship a declaration that names a child slated for a
165
+ later sprint without crashing the boot.
166
+
167
+ ## Access policy (visibility tier)
168
+
169
+ Atoms may declare an ADR-017 access tier. The contract performs no
170
+ enforcement; downstream surfaces (MCP `list_*`, catalog APIs) gate on
171
+ the value.
172
+
173
+ ```ts
174
+ type AccessPolicy =
175
+ | "public-free" // unauthenticated public catalog
176
+ | "public-paid" // catalog-visible, entitlement-gated at fetch
177
+ | "platform-internal" // platform staff only; never enumerated publicly
178
+ | "tenant-private" // owning tenant only
179
+ | "tenant-shared"; // explicit cross-tenant share (ADR-017)
180
+ ```
181
+
182
+ The field appears in two places:
183
+
184
+ - `AtomRegistration.accessPolicy?` — atom-type default. Useful when the
185
+ entire type is internal (e.g. an audit atom).
186
+ - `ContextSummary.accessPolicy?` — per-instance value. Lets a
187
+ mostly-public atom mark individual instances internal — for example,
188
+ a public `jurisdiction-corpus` catalog where partnership-pending
189
+ jurisdictions are tagged `"platform-internal"` until partnership
190
+ closes.
191
+
192
+ Resolution: per-instance `ContextSummary.accessPolicy` wins when
193
+ present, otherwise fall back to the registration's `accessPolicy`,
194
+ otherwise treat the atom as `"public-free"`. The prompt-builder
195
+ catalog (`registry.describeForPrompt()`) normalizes the registration
196
+ value to `"public-free"` when undeclared so downstream filters branch
197
+ without nullish guards.
198
+
199
+ ## History (`EventAnchoringService`)
200
+
201
+ Every atom mutation flows through `EventAnchoringService.appendEvent`,
202
+ which writes one row to an `atom_events` table. The shipped
203
+ `PostgresEventAnchoringService` writes a deterministic SHA-256 chain
204
+ hash. `prevHash` links each event to the previous event for the same
205
+ `(entityType, entityId)` pair, producing a per-entity hash chain.
206
+
207
+ **Interface-stable / implementation-evolving.** The
208
+ `EventAnchoringService` interface is the contract. The deterministic
209
+ SHA-256 implementation will be replaced with a real cryptographic
210
+ anchor (Merkle root + external ledger anchor) at a later milestone
211
+ without changing the consumer interface. Mark sites that should be
212
+ revisited carry `TODO(M2-C):` markers.
213
+
214
+ The host project owns the `atom_events` schema (table, columns,
215
+ constraints). This library issues raw SQL against the agreed table name
216
+ only and depends on `drizzle-orm`'s `sql` helper for SQL templating.
217
+
218
+ ## VDA wrapping (no-op today)
219
+
220
+ `wrapForStorage(value)` returns
221
+ `{ envelope: { version: 1, vdaApplied: false }, payload: value }` and
222
+ `unwrapFromStorage(stored)` returns `stored.payload`. Consumers call
223
+ these from their write paths today; the no-op becomes a real envelope
224
+ (version chain + tombstone semantics) at a later milestone without
225
+ consumer changes.
226
+
227
+ ## Inline reference syntax
228
+
229
+ The chat layer embeds atoms in prose using `{{atom|type|id|label}}`:
230
+
231
+ ```ts
232
+ parseInlineReferences("see {{atom|task|t1|Pick HVAC}}");
233
+ // -> [
234
+ // { kind: "text", text: "see " },
235
+ // { kind: "atom", reference: { kind: "atom", entityType: "task", entityId: "t1", displayLabel: "Pick HVAC" }, raw: "{{atom|task|t1|Pick HVAC}}" }
236
+ // ]
237
+ ```
238
+
239
+ The delimiter is `|`. The previous shape used `:` and could not
240
+ represent Spec 51 entityIds that themselves contain `:` (e.g.
241
+ `parcel-briefing:{parcelId}:{intentHash}`). The old shape is no longer
242
+ parsed: there is no dual-parse compatibility path.
243
+
244
+ ## Encumbrance atom types (ADR-020 / ADR-021)
245
+
246
+ Private recorded land-use instruments ship as Zod-validated payloads on
247
+ the `./encumbrances` subpath (v1.2.0+). Types are **never**
248
+ `public-free`; schemas accept only `tenant-private` and
249
+ `tenant-shared`.
250
+
251
+ ```ts
252
+ import {
253
+ RECORDED_INSTRUMENT_SCHEMA,
254
+ RESTRICTION_CLAUSE_SCHEMA,
255
+ ENCUMBRANCE_RENDER_MODES,
256
+ SAMPLE_RECORDED_INSTRUMENT,
257
+ } from "@empressaio/atom-contract/encumbrances";
258
+ ```
259
+
260
+ ## Oil & Gas atom types (ADR-025)
261
+
262
+ O&G operational, land, and capital atoms ship as Zod-validated payloads on
263
+ the `./og` subpath (v1.7.0). Covers the asset spine (well, wellbore,
264
+ completion, zone, pad), production timeseries, equipment state, the land
265
+ leg (mineral-lease, rrc-lease, tract, ownership-interest), and revenue
266
+ allocation units. Obligation (core domain-neutral type) ships in the main
267
+ module, not `./og`.
268
+
269
+ ```ts
270
+ import {
271
+ WELL_SCHEMA,
272
+ MINERAL_LEASE_SCHEMA,
273
+ REVENUE_ALLOCATION_UNIT_SCHEMA,
274
+ SAMPLE_WELL,
275
+ OG_DEFAULT_ACCESS_POLICY,
276
+ } from "@empressaio/atom-contract/og";
277
+ ```
278
+
279
+ | `entityType` | Purpose | Recommended render modes |
280
+ |---|---|---|
281
+ | `recorded-instrument` | Parent instrument; wet PDF via `sourceDocumentCid` | `card`, `compact`, `expanded` |
282
+ | `restriction-clause` | Enforceable snippet; plan-review citation target | `inline` … `focus` (**default `focus`**) |
283
+ | `restriction-corpus` | Subdivision CC&R pack | `card`, `expanded` |
284
+ | `administrative-rule` | Unrecorded HOA guidelines (`legalWeight: advisory`) | `inline`, `compact`, `card`, `expanded` |
285
+ | `constraint-resolution` | Effective constraint lattice (ADR-021) | `card`, `expanded` |
286
+
287
+ Engine `AtomRegistration` literals and ingest producers belong in
288
+ `hauska-engine/packages/atoms/` (cc-agent-E); Cortex Phase 1 may
289
+ validate uploads with these schemas before the engine registry lands.
290
+
291
+ ## Read-contract types (Calibrated Spine F4 / F6 / K6)
292
+
293
+ Widthed, three-axis confidence returned at read time. Unwidthed,
294
+ unsourced confidence is unrepresentable: the estimate is a branded
295
+ nominal type constructible only through `createWidthedConfidence`.
296
+ No derived numbers are stored in this package.
297
+
298
+ ```ts
299
+ import {
300
+ createReadContract,
301
+ createWidthedConfidence,
302
+ READ_CONTRACT_SCHEMA,
303
+ SAMPLE_READ_CONTRACT,
304
+ type ReadContract,
305
+ type CalibrationProvenance,
306
+ } from "@empressaio/atom-contract/read-contract";
307
+ ```
308
+
309
+ | Export | Role |
310
+ |---|---|
311
+ | `WidthedConfidence` | Inseparable estimate + `n` + `intervalWidth` + provenance |
312
+ | `ThreeAxisConfidence` | Accuracy, source-quality, and consequence axes |
313
+ | `ReadContract` | Full read-contract object every surface must emit |
314
+ | `ModelAttributionStamp` | Ledger deposit stamp (model, prompt, atom-set id) |
315
+ | `CalibrationProvenance` | `asserted` \| `backtest` \| `seed` \| `live` |
316
+
317
+ Propagation to MCP, cortex-api, Cortex, extension, and map is a
318
+ consumer-side Wave 2 co-bump after pinning `^1.4.0`.
319
+
320
+ ## Testing utilities
321
+
322
+ Consumer packages import the contract test suite to prove their
323
+ registration is well-formed in one function call:
324
+
325
+ ```ts
326
+ import { describe } from "vitest";
327
+ import { runAtomContractTests } from "@empressaio/atom-contract/testing";
328
+ import { taskAtom } from "./task.reg";
329
+
330
+ describe("task atom contract", () => {
331
+ runAtomContractTests(taskAtom, {
332
+ withFixture: { entityId: "t1", setUp: seedTestData },
333
+ alsoRegister: [/* any composition children */],
334
+ });
335
+ });
336
+ ```
337
+
338
+ The suite asserts:
339
+
340
+ 1. identity is present and `entityType` is non-empty,
341
+ 2. `defaultMode` is in `supportedModes`,
342
+ 3. `contextSummary` returns a valid four-layer shape with
343
+ `historyProvenance` and `scopeFiltered`,
344
+ 4. every composition edge resolves against `alsoRegister + this`,
345
+ 5. inline-reference round-trips for an instance of this atom.
346
+
347
+ `createInMemoryEventService()` provides an in-memory
348
+ `EventAnchoringService` for unit tests that don't need Postgres;
349
+ `createTestRegistry(initial)` is a convenience over
350
+ `createAtomRegistry()`.
351
+
352
+ ## What this package does NOT ship
353
+
354
+ - **Catalog atom registrations.** No `engagement.atom.ts`,
355
+ `code-section.atom.ts`, etc. Catalog atoms live in consumer packages
356
+ (`hauska-engine/packages/atoms/`, product api-servers, etc.) that
357
+ depend on this one. The line: this package owns the registration
358
+ *mechanism* and the contract; consumers own the per-atom *instances*.
359
+ - **React rendering layer.** Type-level render-mode contract only. The
360
+ `<AtomRenderer>`, `<AtomShell>`, per-mode components, focus-store
361
+ wiring, and right-panel state machine all ship in a later sibling
362
+ package.
363
+ - **Cryptographic anchoring of `atom_events`.** `chainHash` is
364
+ deterministic SHA-256 today; Merkle root + external anchor land in a
365
+ later milestone.
366
+ - **Real VDA backing.** `wrapForStorage` / `unwrapFromStorage` are
367
+ no-ops; the real envelope, version chain, and tombstone semantics
368
+ land in a later milestone.
369
+
370
+ ## Lineage
371
+
372
+ This package extracts the workspace-private `@workspace/empressa-atom`
373
+ that lived at `legacy-design-tools/lib/empressa-atom/`. The framework
374
+ is preserved verbatim; only the package name and the `@workspace/db`
375
+ test-time dependency changed.
376
+
377
+ ## License
378
+
379
+ See LICENSE.
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Declarative atom composition.
3
+ *
4
+ * An atom may declare zero or more children — each describing a child
5
+ * entity type, the render mode the child should be drawn in by the parent,
6
+ * and the key under which the parent's `data` exposes the child rows. The
7
+ * registry **consumes** this declaration: it validates referenced child
8
+ * types at registration time and again on `validate()`, and the resolver
9
+ * (`resolveComposition`) produces a typed children list ready for render.
10
+ */
11
+ import type { AtomMode, AtomReference, AnyAtomRegistration } from "./registration.js";
12
+ /**
13
+ * One edge of the composition graph.
14
+ */
15
+ export interface AtomComposition {
16
+ /**
17
+ * Entity type of the child atom. Must resolve in the registry by the
18
+ * time {@link resolveComposition} is called; the boot-time
19
+ * `AtomRegistry.validate()` step also asserts the child is registered
20
+ * unless {@link forwardRef} is `true`.
21
+ */
22
+ childEntityType: string;
23
+ /** Mode the parent renders each child in (typically `"compact"`). */
24
+ childMode: AtomMode;
25
+ /**
26
+ * Key on the parent's `data` payload where the child rows live. The
27
+ * resolver looks up `parentData[dataKey]` and expects an array.
28
+ */
29
+ dataKey: string;
30
+ /**
31
+ * Opt-out of presence validation for this edge. When `true`:
32
+ * - `AtomRegistry.validate()` does not require {@link childEntityType}
33
+ * to be registered, so a parent can ship a composition declaration
34
+ * that names a child atom slated for a later sprint without
35
+ * crashing the boot.
36
+ * - {@link resolveComposition} silently produces zero children for
37
+ * this edge while the child remains unregistered, so the parent's
38
+ * `contextSummary` keeps returning `ok: true` (instead of erroring
39
+ * and forcing a hand-rolled fallback in every consumer).
40
+ * - Once the child atom is registered, both checks resolve normally
41
+ * and child references begin surfacing without further changes to
42
+ * the parent atom's code.
43
+ *
44
+ * Use sparingly — most edges should reference an already-registered
45
+ * child so a typo in `childEntityType` continues to fail the boot
46
+ * validator (the per-edge scope of this opt-out is deliberate so a
47
+ * sibling forward-ref edge doesn't silently mask a typo elsewhere on
48
+ * the same parent).
49
+ */
50
+ forwardRef?: boolean;
51
+ }
52
+ /**
53
+ * Single resolved child returned by {@link resolveComposition}.
54
+ */
55
+ export interface ResolvedChild {
56
+ /** The composition edge that produced this child. */
57
+ composition: AtomComposition;
58
+ /** The child registration in the registry. */
59
+ registration: AnyAtomRegistration;
60
+ /** Stable atom reference suitable for handing to a render binding. */
61
+ reference: AtomReference;
62
+ /** The raw data row from `parentData[dataKey][i]`. */
63
+ data: Record<string, unknown>;
64
+ }
65
+ /**
66
+ * Minimal registry surface the resolver needs. Declared structurally so
67
+ * `composition.ts` doesn't have to import `registry.ts` and create a
68
+ * circular dependency.
69
+ */
70
+ export interface CompositionRegistryView {
71
+ resolve: (entityType: string) => {
72
+ ok: true;
73
+ registration: AnyAtomRegistration;
74
+ } | {
75
+ ok: false;
76
+ error: {
77
+ entityType: string;
78
+ message: string;
79
+ };
80
+ };
81
+ }
82
+ /**
83
+ * Resolve a parent registration's composition edges against `parentData`.
84
+ *
85
+ * For each declared child:
86
+ * - looks up the child entity type in the registry (returns an error
87
+ * variant if missing — never throws),
88
+ * - reads `parentData[dataKey]` (must be an array; missing → empty),
89
+ * - synthesizes a stable {@link AtomReference} per row using `id`,
90
+ * `entityId`, `slug`, or `name` (in that order), falling back to
91
+ * `${parentRef.entityId}-${dataKey}-${index}`.
92
+ *
93
+ * Edges marked `forwardRef: true` whose child is still unregistered at
94
+ * lookup time produce zero children silently rather than contributing
95
+ * an error — the parent has explicitly opted in to that behavior so its
96
+ * declaration can ship before the child catalog atom does.
97
+ *
98
+ * @returns A list of {@link ResolvedChild} on success, or `{ ok: false,
99
+ * errors }` enumerating every missing non-forward-ref child entity
100
+ * type. The caller decides whether to dev-warn or hard-fail.
101
+ */
102
+ export declare function resolveComposition(parentRegistration: AnyAtomRegistration, parentRef: AtomReference, parentData: Record<string, unknown>, registry: CompositionRegistryView): {
103
+ ok: true;
104
+ children: ResolvedChild[];
105
+ } | {
106
+ ok: false;
107
+ errors: ReadonlyArray<{
108
+ childEntityType: string;
109
+ message: string;
110
+ }>;
111
+ };
112
+ //# sourceMappingURL=composition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../src/composition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEtF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,SAAS,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,WAAW,EAAE,eAAe,CAAC;IAE7B,8CAA8C;IAC9C,YAAY,EAAE,mBAAmB,CAAC;IAElC,sEAAsE;IACtE,SAAS,EAAE,aAAa,CAAC;IAEzB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,CACP,UAAU,EAAE,MAAM,KAEhB;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,YAAY,EAAE,mBAAmB,CAAA;KAAE,GAC/C;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACnE;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAChC,kBAAkB,EAAE,mBAAmB,EACvC,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,EAAE,uBAAuB,GAE/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,GACvC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,aAAa,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE,CA2CJ"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Declarative atom composition.
3
+ *
4
+ * An atom may declare zero or more children — each describing a child
5
+ * entity type, the render mode the child should be drawn in by the parent,
6
+ * and the key under which the parent's `data` exposes the child rows. The
7
+ * registry **consumes** this declaration: it validates referenced child
8
+ * types at registration time and again on `validate()`, and the resolver
9
+ * (`resolveComposition`) produces a typed children list ready for render.
10
+ */
11
+ function pickIdFrom(row, fallback) {
12
+ const candidate = row.id ?? row.entityId ?? row.slug ?? row.name;
13
+ if (typeof candidate === "string" && candidate.length > 0)
14
+ return candidate;
15
+ if (typeof candidate === "number")
16
+ return String(candidate);
17
+ return fallback;
18
+ }
19
+ /**
20
+ * Resolve a parent registration's composition edges against `parentData`.
21
+ *
22
+ * For each declared child:
23
+ * - looks up the child entity type in the registry (returns an error
24
+ * variant if missing — never throws),
25
+ * - reads `parentData[dataKey]` (must be an array; missing → empty),
26
+ * - synthesizes a stable {@link AtomReference} per row using `id`,
27
+ * `entityId`, `slug`, or `name` (in that order), falling back to
28
+ * `${parentRef.entityId}-${dataKey}-${index}`.
29
+ *
30
+ * Edges marked `forwardRef: true` whose child is still unregistered at
31
+ * lookup time produce zero children silently rather than contributing
32
+ * an error — the parent has explicitly opted in to that behavior so its
33
+ * declaration can ship before the child catalog atom does.
34
+ *
35
+ * @returns A list of {@link ResolvedChild} on success, or `{ ok: false,
36
+ * errors }` enumerating every missing non-forward-ref child entity
37
+ * type. The caller decides whether to dev-warn or hard-fail.
38
+ */
39
+ export function resolveComposition(parentRegistration, parentRef, parentData, registry) {
40
+ const composition = parentRegistration.composition;
41
+ const errors = [];
42
+ const children = [];
43
+ for (const edge of composition) {
44
+ const resolved = registry.resolve(edge.childEntityType);
45
+ if (!resolved.ok) {
46
+ if (edge.forwardRef) {
47
+ continue;
48
+ }
49
+ errors.push({
50
+ childEntityType: edge.childEntityType,
51
+ message: resolved.error.message,
52
+ });
53
+ continue;
54
+ }
55
+ const raw = parentData[edge.dataKey];
56
+ const rows = Array.isArray(raw)
57
+ ? raw
58
+ : [];
59
+ rows.forEach((row, i) => {
60
+ if (row === null || typeof row !== "object")
61
+ return;
62
+ const childId = pickIdFrom(row, `${parentRef.entityId}-${edge.dataKey}-${i}`);
63
+ children.push({
64
+ composition: edge,
65
+ registration: resolved.registration,
66
+ reference: {
67
+ kind: "atom",
68
+ entityType: edge.childEntityType,
69
+ entityId: childId,
70
+ mode: edge.childMode,
71
+ },
72
+ data: row,
73
+ });
74
+ });
75
+ }
76
+ if (errors.length > 0)
77
+ return { ok: false, errors };
78
+ return { ok: true, children };
79
+ }
80
+ //# sourceMappingURL=composition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.js","sourceRoot":"","sources":["../src/composition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA8EH,SAAS,UAAU,CAAC,GAA4B,EAAE,QAAgB;IAChE,MAAM,SAAS,GAAG,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC;IACjE,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5E,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,kBAAkB,CAChC,kBAAuC,EACvC,SAAwB,EACxB,UAAmC,EACnC,QAAiC;IAOjC,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC;IACnD,MAAM,MAAM,GAAwD,EAAE,CAAC;IACvE,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,MAAM,CAAC,IAAI,CAAC;gBACV,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO;aAChC,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,IAAI,GAAmC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAC7D,CAAC,CAAE,GAAsC;YACzC,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACtB,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,OAAO;YACpD,MAAM,OAAO,GAAG,UAAU,CACxB,GAAG,EACH,GAAG,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,CAC7C,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC;gBACZ,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,QAAQ,CAAC,YAAY;gBACnC,SAAS,EAAE;oBACT,IAAI,EAAE,MAAM;oBACZ,UAAU,EAAE,IAAI,CAAC,eAAe;oBAChC,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE,IAAI,CAAC,SAAS;iBACrB;gBACD,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Architecture-homes conformance target constants (doc 02).
3
+ *
4
+ * Every atom family must satisfy the shape validated by
5
+ * {@link validateAtomConformance} against
6
+ * {@link ATOM_CONFORMANCE_TARGET_VERSION}.
7
+ */
8
+ import { z } from "zod";
9
+ import type { AccessPolicy } from "../registration.js";
10
+ /**
11
+ * Pin every consumer co-bump to this semver when adopting the
12
+ * conformance target or downloadable-atom export shape.
13
+ */
14
+ export declare const ATOM_CONFORMANCE_TARGET_VERSION: "1.5.0";
15
+ export type AtomConformanceTargetVersion = typeof ATOM_CONFORMANCE_TARGET_VERSION;
16
+ /** Data-level atoms carry signed history; app-level workflow containers skip it. */
17
+ export type AtomTier = "data" | "app";
18
+ export declare const ATOM_TIER_VALUES: ReadonlyArray<AtomTier>;
19
+ export declare const ACCESS_POLICY_VALUES: ReadonlyArray<AccessPolicy>;
20
+ export declare const ACCESS_POLICY_SCHEMA: z.ZodEnum<["public-free", "public-paid", "platform-internal", "tenant-private", "tenant-shared"]>;
21
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/conformance/common.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,eAAO,MAAM,+BAA+B,EAAG,OAAgB,CAAC;AAEhE,MAAM,MAAM,4BAA4B,GACtC,OAAO,+BAA+B,CAAC;AAEzC,oFAAoF;AACpF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtC,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,QAAQ,CAAmB,CAAC;AAEzE,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,YAAY,CAM5D,CAAC;AAEF,eAAO,MAAM,oBAAoB,mGAM/B,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Architecture-homes conformance target constants (doc 02).
3
+ *
4
+ * Every atom family must satisfy the shape validated by
5
+ * {@link validateAtomConformance} against
6
+ * {@link ATOM_CONFORMANCE_TARGET_VERSION}.
7
+ */
8
+ import { z } from "zod";
9
+ /**
10
+ * Pin every consumer co-bump to this semver when adopting the
11
+ * conformance target or downloadable-atom export shape.
12
+ */
13
+ export const ATOM_CONFORMANCE_TARGET_VERSION = "1.5.0";
14
+ export const ATOM_TIER_VALUES = ["data", "app"];
15
+ export const ACCESS_POLICY_VALUES = [
16
+ "public-free",
17
+ "public-paid",
18
+ "platform-internal",
19
+ "tenant-private",
20
+ "tenant-shared",
21
+ ];
22
+ export const ACCESS_POLICY_SCHEMA = z.enum([
23
+ "public-free",
24
+ "public-paid",
25
+ "platform-internal",
26
+ "tenant-private",
27
+ "tenant-shared",
28
+ ]);
29
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/conformance/common.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;GAGG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,OAAgB,CAAC;AAQhE,MAAM,CAAC,MAAM,gBAAgB,GAA4B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,oBAAoB,GAAgC;IAC/D,aAAa;IACb,aAAa;IACb,mBAAmB;IACnB,gBAAgB;IAChB,eAAe;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC;IACzC,aAAa;IACb,aAAa;IACb,mBAAmB;IACnB,gBAAgB;IAChB,eAAe;CAChB,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { AtomEvent } from "../history.js";
2
+ import type { AtomConformanceTarget } from "./validate.js";
3
+ type ChainEventSeed = Omit<AtomEvent, "chainHash" | "prevHash"> & {
4
+ prevHash?: string | null;
5
+ chainHash?: string;
6
+ };
7
+ /** Build a gap-free signed chain with recomputed hashes for tests. */
8
+ export declare function buildValidSignedEventChain(events: ReadonlyArray<ChainEventSeed>): AtomEvent[];
9
+ export declare const SAMPLE_DATA_CONFORMANCE_EVENTS: AtomEvent[];
10
+ export declare const SAMPLE_DATA_CONFORMANCE_TARGET: AtomConformanceTarget;
11
+ export declare const SAMPLE_APP_CONFORMANCE_TARGET: AtomConformanceTarget;
12
+ export {};
13
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/conformance/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAI3D,KAAK,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG;IAChE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,GACpC,SAAS,EAAE,CAmBb;AAED,eAAO,MAAM,8BAA8B,aAsBzC,CAAC;AAEH,eAAO,MAAM,8BAA8B,EAAE,qBAS5C,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,qBAK3C,CAAC"}