simfile 0.0.1

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 (249) hide show
  1. package/README.md +143 -0
  2. package/dist/cli/index.d.ts +3 -0
  3. package/dist/cli/index.d.ts.map +1 -0
  4. package/dist/cli/index.js +348 -0
  5. package/dist/coverage/index.d.ts +2 -0
  6. package/dist/coverage/index.d.ts.map +1 -0
  7. package/dist/coverage/index.js +1 -0
  8. package/dist/coverage/matrix.d.ts +21 -0
  9. package/dist/coverage/matrix.d.ts.map +1 -0
  10. package/dist/coverage/matrix.js +173 -0
  11. package/dist/coverage/render.d.ts +3 -0
  12. package/dist/coverage/render.d.ts.map +1 -0
  13. package/dist/coverage/render.js +26 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +7 -0
  17. package/dist/kernel/duration.d.ts +9 -0
  18. package/dist/kernel/duration.d.ts.map +1 -0
  19. package/dist/kernel/duration.js +44 -0
  20. package/dist/kernel/index.d.ts +4 -0
  21. package/dist/kernel/index.d.ts.map +1 -0
  22. package/dist/kernel/index.js +3 -0
  23. package/dist/kernel/range.d.ts +6 -0
  24. package/dist/kernel/range.d.ts.map +1 -0
  25. package/dist/kernel/range.js +16 -0
  26. package/dist/kernel/stochastic.d.ts +10 -0
  27. package/dist/kernel/stochastic.d.ts.map +1 -0
  28. package/dist/kernel/stochastic.js +25 -0
  29. package/dist/ledger/index.d.ts +4 -0
  30. package/dist/ledger/index.d.ts.map +1 -0
  31. package/dist/ledger/index.js +3 -0
  32. package/dist/ledger/markers.d.ts +46 -0
  33. package/dist/ledger/markers.d.ts.map +1 -0
  34. package/dist/ledger/markers.js +108 -0
  35. package/dist/ledger/stable.d.ts +65 -0
  36. package/dist/ledger/stable.d.ts.map +1 -0
  37. package/dist/ledger/stable.js +78 -0
  38. package/dist/ledger/validation.d.ts +16 -0
  39. package/dist/ledger/validation.d.ts.map +1 -0
  40. package/dist/ledger/validation.js +127 -0
  41. package/dist/moltnet/index.d.ts +3 -0
  42. package/dist/moltnet/index.d.ts.map +1 -0
  43. package/dist/moltnet/index.js +2 -0
  44. package/dist/moltnet/transcript-export.d.ts +34 -0
  45. package/dist/moltnet/transcript-export.d.ts.map +1 -0
  46. package/dist/moltnet/transcript-export.js +68 -0
  47. package/dist/moltnet/world-participant.d.ts +77 -0
  48. package/dist/moltnet/world-participant.d.ts.map +1 -0
  49. package/dist/moltnet/world-participant.js +221 -0
  50. package/dist/observe/artifacts.d.ts +16 -0
  51. package/dist/observe/artifacts.d.ts.map +1 -0
  52. package/dist/observe/artifacts.js +31 -0
  53. package/dist/observe/causalStreams.d.ts +19 -0
  54. package/dist/observe/causalStreams.d.ts.map +1 -0
  55. package/dist/observe/causalStreams.js +38 -0
  56. package/dist/observe/compute.d.ts +17 -0
  57. package/dist/observe/compute.d.ts.map +1 -0
  58. package/dist/observe/compute.js +97 -0
  59. package/dist/observe/index.d.ts +11 -0
  60. package/dist/observe/index.d.ts.map +1 -0
  61. package/dist/observe/index.js +10 -0
  62. package/dist/observe/manifest.d.ts +79 -0
  63. package/dist/observe/manifest.d.ts.map +1 -0
  64. package/dist/observe/manifest.js +87 -0
  65. package/dist/observe/memoryBanks.d.ts +38 -0
  66. package/dist/observe/memoryBanks.d.ts.map +1 -0
  67. package/dist/observe/memoryBanks.js +86 -0
  68. package/dist/observe/observe.d.ts +32 -0
  69. package/dist/observe/observe.d.ts.map +1 -0
  70. package/dist/observe/observe.js +73 -0
  71. package/dist/observe/report.d.ts +165 -0
  72. package/dist/observe/report.d.ts.map +1 -0
  73. package/dist/observe/report.js +138 -0
  74. package/dist/observe/seedSpread.d.ts +49 -0
  75. package/dist/observe/seedSpread.d.ts.map +1 -0
  76. package/dist/observe/seedSpread.js +262 -0
  77. package/dist/observe/seedSpreadArtifacts.d.ts +49 -0
  78. package/dist/observe/seedSpreadArtifacts.d.ts.map +1 -0
  79. package/dist/observe/seedSpreadArtifacts.js +118 -0
  80. package/dist/observe/spreadMatcher.d.ts +45 -0
  81. package/dist/observe/spreadMatcher.d.ts.map +1 -0
  82. package/dist/observe/spreadMatcher.js +124 -0
  83. package/dist/report/index.d.ts +4 -0
  84. package/dist/report/index.d.ts.map +1 -0
  85. package/dist/report/index.js +3 -0
  86. package/dist/report/probeArtifact.d.ts +26 -0
  87. package/dist/report/probeArtifact.d.ts.map +1 -0
  88. package/dist/report/probeArtifact.js +119 -0
  89. package/dist/report/probes.d.ts +52 -0
  90. package/dist/report/probes.d.ts.map +1 -0
  91. package/dist/report/probes.js +164 -0
  92. package/dist/report/score.d.ts +27 -0
  93. package/dist/report/score.d.ts.map +1 -0
  94. package/dist/report/score.js +14 -0
  95. package/dist/report/transcripts.d.ts +12 -0
  96. package/dist/report/transcripts.d.ts.map +1 -0
  97. package/dist/report/transcripts.js +17 -0
  98. package/dist/runtime/causal-fixture.d.ts +26 -0
  99. package/dist/runtime/causal-fixture.d.ts.map +1 -0
  100. package/dist/runtime/causal-fixture.js +36 -0
  101. package/dist/runtime/clock.d.ts +25 -0
  102. package/dist/runtime/clock.d.ts.map +1 -0
  103. package/dist/runtime/clock.js +63 -0
  104. package/dist/runtime/condition.d.ts +55 -0
  105. package/dist/runtime/condition.d.ts.map +1 -0
  106. package/dist/runtime/condition.js +122 -0
  107. package/dist/runtime/emit-causal-fixture.d.ts +2 -0
  108. package/dist/runtime/emit-causal-fixture.d.ts.map +1 -0
  109. package/dist/runtime/emit-causal-fixture.js +45 -0
  110. package/dist/runtime/expression.d.ts +11 -0
  111. package/dist/runtime/expression.d.ts.map +1 -0
  112. package/dist/runtime/expression.js +305 -0
  113. package/dist/runtime/numeric.d.ts +7 -0
  114. package/dist/runtime/numeric.d.ts.map +1 -0
  115. package/dist/runtime/numeric.js +11 -0
  116. package/dist/runtime/rule-actions.d.ts +5 -0
  117. package/dist/runtime/rule-actions.d.ts.map +1 -0
  118. package/dist/runtime/rule-actions.js +82 -0
  119. package/dist/runtime/run-record.d.ts +73 -0
  120. package/dist/runtime/run-record.d.ts.map +1 -0
  121. package/dist/runtime/run-record.js +179 -0
  122. package/dist/runtime/step-tick.d.ts +43 -0
  123. package/dist/runtime/step-tick.d.ts.map +1 -0
  124. package/dist/runtime/step-tick.js +177 -0
  125. package/dist/runtime/trace-compile.d.ts +66 -0
  126. package/dist/runtime/trace-compile.d.ts.map +1 -0
  127. package/dist/runtime/trace-compile.js +157 -0
  128. package/dist/runtime/trace-export.d.ts +5 -0
  129. package/dist/runtime/trace-export.d.ts.map +1 -0
  130. package/dist/runtime/trace-export.js +4 -0
  131. package/dist/runtime/trace-run.d.ts +15 -0
  132. package/dist/runtime/trace-run.d.ts.map +1 -0
  133. package/dist/runtime/trace-run.js +92 -0
  134. package/dist/runtime/trace.d.ts +10 -0
  135. package/dist/runtime/trace.d.ts.map +1 -0
  136. package/dist/runtime/trace.js +9 -0
  137. package/dist/runtime/types.d.ts +61 -0
  138. package/dist/runtime/types.d.ts.map +1 -0
  139. package/dist/runtime/types.js +1 -0
  140. package/dist/runtime/viewer-trace.d.ts +64 -0
  141. package/dist/runtime/viewer-trace.d.ts.map +1 -0
  142. package/dist/runtime/viewer-trace.js +164 -0
  143. package/dist/runtime/world-act.d.ts +55 -0
  144. package/dist/runtime/world-act.d.ts.map +1 -0
  145. package/dist/runtime/world-act.js +156 -0
  146. package/dist/schema/binding.d.ts +23 -0
  147. package/dist/schema/binding.d.ts.map +1 -0
  148. package/dist/schema/binding.js +249 -0
  149. package/dist/schema/index.d.ts +5 -0
  150. package/dist/schema/index.d.ts.map +1 -0
  151. package/dist/schema/index.js +4 -0
  152. package/dist/schema/model.d.ts +244 -0
  153. package/dist/schema/model.d.ts.map +1 -0
  154. package/dist/schema/model.js +222 -0
  155. package/dist/schema/parse.d.ts +10 -0
  156. package/dist/schema/parse.d.ts.map +1 -0
  157. package/dist/schema/parse.js +15 -0
  158. package/dist/schema/semantic.d.ts +3 -0
  159. package/dist/schema/semantic.d.ts.map +1 -0
  160. package/dist/schema/semantic.js +135 -0
  161. package/dist/sims/composeRunManifest.d.ts +54 -0
  162. package/dist/sims/composeRunManifest.d.ts.map +1 -0
  163. package/dist/sims/composeRunManifest.js +40 -0
  164. package/dist/sims/composedJungianSimDriver.d.ts +50 -0
  165. package/dist/sims/composedJungianSimDriver.d.ts.map +1 -0
  166. package/dist/sims/composedJungianSimDriver.js +199 -0
  167. package/dist/sims/composedOfficeSimDriver.d.ts +53 -0
  168. package/dist/sims/composedOfficeSimDriver.d.ts.map +1 -0
  169. package/dist/sims/composedOfficeSimDriver.js +162 -0
  170. package/dist/sims/exchangeWait.d.ts +56 -0
  171. package/dist/sims/exchangeWait.d.ts.map +1 -0
  172. package/dist/sims/exchangeWait.js +66 -0
  173. package/dist/sims/index.d.ts +14 -0
  174. package/dist/sims/index.d.ts.map +1 -0
  175. package/dist/sims/index.js +13 -0
  176. package/dist/sims/moltnetRoomClient.d.ts +47 -0
  177. package/dist/sims/moltnetRoomClient.d.ts.map +1 -0
  178. package/dist/sims/moltnetRoomClient.js +41 -0
  179. package/dist/sims/poll.d.ts +19 -0
  180. package/dist/sims/poll.d.ts.map +1 -0
  181. package/dist/sims/poll.js +23 -0
  182. package/dist/sims/spawnfileCli.d.ts +49 -0
  183. package/dist/sims/spawnfileCli.d.ts.map +1 -0
  184. package/dist/sims/spawnfileCli.js +90 -0
  185. package/dist/sims/spawnfileReceipts.d.ts +76 -0
  186. package/dist/sims/spawnfileReceipts.d.ts.map +1 -0
  187. package/dist/sims/spawnfileReceipts.js +107 -0
  188. package/dist/sims/worldDrivenOfficeSimDriver.d.ts +59 -0
  189. package/dist/sims/worldDrivenOfficeSimDriver.d.ts.map +1 -0
  190. package/dist/sims/worldDrivenOfficeSimDriver.js +182 -0
  191. package/dist/sims/worldLedgerWriter.d.ts +32 -0
  192. package/dist/sims/worldLedgerWriter.d.ts.map +1 -0
  193. package/dist/sims/worldLedgerWriter.js +39 -0
  194. package/dist/sims/worldSeedLint.d.ts +42 -0
  195. package/dist/sims/worldSeedLint.d.ts.map +1 -0
  196. package/dist/sims/worldSeedLint.js +73 -0
  197. package/dist/sims/worldTickIngest.d.ts +27 -0
  198. package/dist/sims/worldTickIngest.d.ts.map +1 -0
  199. package/dist/sims/worldTickIngest.js +35 -0
  200. package/dist/sims/worldTickLoop.d.ts +64 -0
  201. package/dist/sims/worldTickLoop.d.ts.map +1 -0
  202. package/dist/sims/worldTickLoop.js +122 -0
  203. package/dist/view/engineProvenance.d.ts +46 -0
  204. package/dist/view/engineProvenance.d.ts.map +1 -0
  205. package/dist/view/engineProvenance.js +76 -0
  206. package/dist/view/index.d.ts +14 -0
  207. package/dist/view/index.d.ts.map +1 -0
  208. package/dist/view/index.js +107 -0
  209. package/dist/view/membranes.d.ts +14 -0
  210. package/dist/view/membranes.d.ts.map +1 -0
  211. package/dist/view/membranes.js +127 -0
  212. package/dist/view/runDetect.d.ts +2 -0
  213. package/dist/view/runDetect.d.ts.map +1 -0
  214. package/dist/view/runDetect.js +47 -0
  215. package/dist/view/runRawArtifacts.d.ts +48 -0
  216. package/dist/view/runRawArtifacts.d.ts.map +1 -0
  217. package/dist/view/runRawArtifacts.js +143 -0
  218. package/dist/view/runTimeline.d.ts +24 -0
  219. package/dist/view/runTimeline.d.ts.map +1 -0
  220. package/dist/view/runTimeline.js +204 -0
  221. package/dist/view/runTimelineRecords.d.ts +42 -0
  222. package/dist/view/runTimelineRecords.d.ts.map +1 -0
  223. package/dist/view/runTimelineRecords.js +244 -0
  224. package/dist/view/runTimelineRefs.d.ts +27 -0
  225. package/dist/view/runTimelineRefs.d.ts.map +1 -0
  226. package/dist/view/runTimelineRefs.js +31 -0
  227. package/dist/view/runTimelineTypes.d.ts +99 -0
  228. package/dist/view/runTimelineTypes.d.ts.map +1 -0
  229. package/dist/view/runTimelineTypes.js +1 -0
  230. package/dist/view/runViewModel.d.ts +21 -0
  231. package/dist/view/runViewModel.d.ts.map +1 -0
  232. package/dist/view/runViewModel.js +66 -0
  233. package/dist/view/runViewModelCompute.d.ts +24 -0
  234. package/dist/view/runViewModelCompute.d.ts.map +1 -0
  235. package/dist/view/runViewModelCompute.js +157 -0
  236. package/dist/view/runViewModelTypes.d.ts +177 -0
  237. package/dist/view/runViewModelTypes.d.ts.map +1 -0
  238. package/dist/view/runViewModelTypes.js +1 -0
  239. package/dist/view/runWorldTrace.d.ts +97 -0
  240. package/dist/view/runWorldTrace.d.ts.map +1 -0
  241. package/dist/view/runWorldTrace.js +88 -0
  242. package/dist/view/server.d.ts +12 -0
  243. package/dist/view/server.d.ts.map +1 -0
  244. package/dist/view/server.js +306 -0
  245. package/package.json +65 -0
  246. package/web/dist/assets/index-CJHLjfsG.js +49 -0
  247. package/web/dist/assets/index-DJOsPsU8.css +1 -0
  248. package/web/dist/index.html +13 -0
  249. package/web/dist/models/AnimatedMushnub.glb +0 -0
@@ -0,0 +1,222 @@
1
+ import { z } from "zod";
2
+ const identifierPattern = "[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*";
3
+ export const simfileIdentifierSchema = z.string().regex(new RegExp(`^${identifierPattern}$`), {
4
+ message: "expected lowercase identifier with letters, numbers, dashes, or underscores"
5
+ });
6
+ const simfileDurationSchema = z.string().regex(/^(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:ms|s|m|h|d|w)$/u, {
7
+ message: "expected duration string (e.g. 20s, 1.5m, 2h)"
8
+ });
9
+ export const simfileRangeSchema = z.string().regex(new RegExp(`^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?\\.\\.-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$`), { message: "expected range string like 0..1" }).superRefine((value, context) => {
10
+ const [start, end] = value.split("..");
11
+ if (Number.parseFloat(start) >= Number.parseFloat(end)) {
12
+ context.addIssue({
13
+ code: z.ZodIssueCode.custom,
14
+ message: "range lower bound must be less than upper bound",
15
+ path: []
16
+ });
17
+ }
18
+ });
19
+ const scopeAgentPattern = new RegExp(`^agent:${identifierPattern}$`);
20
+ const scopeTeamPattern = new RegExp(`^team:${identifierPattern}$`);
21
+ const scopeRoomPattern = new RegExp(`^room:${identifierPattern}:${identifierPattern}$`);
22
+ const scopePairPattern = new RegExp(`^pair:${identifierPattern}:${identifierPattern}$`);
23
+ const simfileRoomScopeSchema = z.string().regex(scopeRoomPattern, {
24
+ message: "expected room scope (room:<network>:<room>)"
25
+ });
26
+ const simfileAgentScopeSchema = z.string().regex(scopeAgentPattern, {
27
+ message: "expected agent scope (agent:<id>)"
28
+ });
29
+ const simfileScopeSchema = z.string().refine((value) => {
30
+ return value === "global"
31
+ || scopeAgentPattern.test(value)
32
+ || scopeTeamPattern.test(value)
33
+ || scopeRoomPattern.test(value)
34
+ || scopePairPattern.test(value);
35
+ }, {
36
+ message: "expected scope string global | agent:<id> | room:<network>:<room> | team:<id> | pair:<a>:<b>"
37
+ });
38
+ export const simfileEventKinds = [
39
+ "clock.sync",
40
+ "rule.fired",
41
+ "world.message",
42
+ "world.dm",
43
+ "world.act",
44
+ "wake.recommended",
45
+ "marker.seen"
46
+ ];
47
+ const simfileEventKindSchema = z.enum(simfileEventKinds);
48
+ const simfileWhenLeafSchema = z.union([
49
+ z.object({
50
+ variable: simfileIdentifierSchema,
51
+ above: z.number().optional(),
52
+ below: z.number().optional(),
53
+ for: simfileDurationSchema.optional()
54
+ }).strict().refine((value) => value.above !== undefined || value.below !== undefined, {
55
+ message: "variable condition requires above and/or below"
56
+ }),
57
+ z.object({
58
+ phase: simfileIdentifierSchema
59
+ }).strict(),
60
+ z.object({
61
+ event: simfileEventKindSchema,
62
+ target: z.string().optional(),
63
+ actor: z.string().optional(),
64
+ scope: simfileScopeSchema.optional()
65
+ }).strict()
66
+ ]);
67
+ export const simfileWhenSchema = z.lazy(() => z.union([
68
+ simfileWhenLeafSchema,
69
+ z.object({
70
+ all: z.array(simfileWhenSchema).min(1)
71
+ }).strict(),
72
+ z.object({
73
+ any: z.array(simfileWhenSchema).min(1)
74
+ }).strict(),
75
+ z.object({
76
+ not: simfileWhenSchema
77
+ }).strict()
78
+ ]));
79
+ export const simfileClockSchema = z.object({
80
+ seed: z.string().min(1),
81
+ tick: simfileDurationSchema,
82
+ sim_per_tick: simfileDurationSchema.optional(),
83
+ phases: z.record(simfileIdentifierSchema, z.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/u)).default({})
84
+ }).strict();
85
+ const simfileMeasureSchema = z.object({
86
+ kind: z.enum(["messages_in", "token_mentions", "marker_violations", "distinct_speakers", "mentions_of", "ticks_since_last_message"]),
87
+ scope: simfileScopeSchema.optional(),
88
+ window: simfileDurationSchema
89
+ }).strict();
90
+ const simfileDerivedSchema = z.object({
91
+ eq: z.string().min(1)
92
+ }).strict();
93
+ const simfileVariableSchema = z.object({
94
+ scope: simfileScopeSchema,
95
+ initial: z.number().optional(),
96
+ range: simfileRangeSchema,
97
+ measure: simfileMeasureSchema.optional(),
98
+ derive: simfileDerivedSchema.optional(),
99
+ fed_by: simfileIdentifierSchema.optional()
100
+ }).refine((value) => {
101
+ const sourceCount = Number(value.measure !== undefined) + Number(value.derive !== undefined) + Number(value.fed_by !== undefined);
102
+ return sourceCount <= 1;
103
+ }, {
104
+ message: "variables must use at most one of measure, derive, or fed_by"
105
+ }).strict();
106
+ const simfileGeneratorDeterministicSchema = z.object({
107
+ kind: z.literal("deterministic"),
108
+ when: simfileWhenSchema.optional(),
109
+ variable: simfileIdentifierSchema,
110
+ delta: z.number().optional(),
111
+ delta_eq: z.string().optional(),
112
+ set_eq: z.string().optional()
113
+ }).refine((value) => {
114
+ const writerCount = Number(value.delta !== undefined) + Number(value.delta_eq !== undefined) + Number(value.set_eq !== undefined);
115
+ return writerCount === 1;
116
+ }, {
117
+ message: "deterministic generators require exactly one of delta, delta_eq, or set_eq"
118
+ }).strict();
119
+ const simfileGeneratorStochasticSchema = z.object({
120
+ kind: z.literal("stochastic"),
121
+ when: simfileWhenSchema.optional(),
122
+ variable: simfileIdentifierSchema,
123
+ uniform: z.tuple([z.number(), z.number()])
124
+ }).strict();
125
+ export const simfileGeneratorSchema = z.union([
126
+ simfileGeneratorDeterministicSchema,
127
+ simfileGeneratorStochasticSchema
128
+ ]);
129
+ export const simfileRuleActionSchema = z.union([
130
+ z.object({
131
+ action: z.literal("moltnet:message"),
132
+ to: simfileRoomScopeSchema,
133
+ content: z.string().min(1)
134
+ }).strict(),
135
+ z.object({
136
+ action: z.literal("moltnet:dm"),
137
+ to: simfileAgentScopeSchema,
138
+ content: z.string().min(1)
139
+ }).strict(),
140
+ z.object({
141
+ action: z.literal("wake:recommend"),
142
+ to: simfileRoomScopeSchema
143
+ }).strict(),
144
+ z.object({
145
+ action: z.literal("variable:set"),
146
+ variable: simfileIdentifierSchema,
147
+ value: z.number()
148
+ }).strict(),
149
+ z.object({
150
+ action: z.literal("variable:delta"),
151
+ variable: simfileIdentifierSchema,
152
+ value: z.number()
153
+ }).strict()
154
+ ]);
155
+ export const simfileRuleSchema = z.object({
156
+ fire: z.enum(["once", "per_crossing"]).default("per_crossing"),
157
+ when: simfileWhenSchema,
158
+ do: z.array(simfileRuleActionSchema).min(1)
159
+ }).strict();
160
+ export const simfileLedgerSchema = z.object({
161
+ store: z.object({
162
+ kind: z.enum(["jsonl", "sqlite", "postgres"]).default("jsonl"),
163
+ path: z.string().min(1).optional()
164
+ }).strict()
165
+ }).strict();
166
+ export const simfileTelemetrySchema = z.object({
167
+ snapshot_every: z.number().int().positive().optional()
168
+ }).strict();
169
+ export const simfileMarkerSchema = z.object({
170
+ text: z.array(z.string().min(1)).optional(),
171
+ mode: z.enum(["containment", "propagation"]),
172
+ scopes: z.array(simfileScopeSchema).min(1)
173
+ }).strict();
174
+ const simfileProbeExpectationSchema = z.union([
175
+ z.object({ at_least: z.number().int().nonnegative() }).strict(),
176
+ z.object({ at_most: z.number().int().nonnegative() }).strict(),
177
+ z.object({ always: z.literal(true) }).strict(),
178
+ z.object({ at_end: z.literal(true) }).strict()
179
+ ]).superRefine((expectation, context) => {
180
+ const keys = Object.keys(expectation);
181
+ if (keys.length !== 1) {
182
+ context.addIssue({
183
+ code: z.ZodIssueCode.custom,
184
+ message: "expect must contain one of at_least, at_most, always, or at_end",
185
+ path: []
186
+ });
187
+ }
188
+ });
189
+ export const simfileProbeSchema = z.object({
190
+ when: simfileWhenSchema,
191
+ expect: simfileProbeExpectationSchema,
192
+ after: simfileWhenSchema.optional(),
193
+ within: simfileDurationSchema.optional()
194
+ }).superRefine((value, context) => {
195
+ if (value.within !== undefined && value.after === undefined) {
196
+ context.addIssue({
197
+ code: z.ZodIssueCode.custom,
198
+ message: "within requires after",
199
+ path: ["within"]
200
+ });
201
+ }
202
+ if (value.after !== undefined && value.within === undefined) {
203
+ context.addIssue({
204
+ code: z.ZodIssueCode.custom,
205
+ message: "after requires within",
206
+ path: ["after"]
207
+ });
208
+ }
209
+ }).strict();
210
+ export const simfileSchema = z.object({
211
+ simfile_version: z.literal("0.1"),
212
+ name: simfileIdentifierSchema,
213
+ spawnfile: z.string().optional(),
214
+ clock: simfileClockSchema,
215
+ variables: z.record(simfileIdentifierSchema, simfileVariableSchema).default({}),
216
+ generators: z.record(simfileIdentifierSchema, simfileGeneratorSchema).default({}),
217
+ rules: z.record(simfileIdentifierSchema, simfileRuleSchema).default({}),
218
+ ledger: simfileLedgerSchema.optional(),
219
+ telemetry: simfileTelemetrySchema.optional(),
220
+ markers: z.record(simfileIdentifierSchema, simfileMarkerSchema).default({}),
221
+ probes: z.record(simfileIdentifierSchema, simfileProbeSchema).default({})
222
+ }).strict();
@@ -0,0 +1,10 @@
1
+ import { type Simfile } from "./model.js";
2
+ export interface ParseSimfileOptions {
3
+ path?: string;
4
+ }
5
+ export interface ParseSimfileResult {
6
+ simfile: Simfile;
7
+ warnings: string[];
8
+ }
9
+ export declare const parseSimfileSource: (source: string, options?: ParseSimfileOptions) => ParseSimfileResult;
10
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/schema/parse.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAUD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,UAAS,mBAAwB,KAChC,kBAKF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import YAML from "yaml";
2
+ import { simfileSchema } from "./model.js";
3
+ import { validateSimfileSemantics } from "./semantic.js";
4
+ const parseRawDocument = (source, path) => {
5
+ if (path?.endsWith(".json")) {
6
+ return JSON.parse(source);
7
+ }
8
+ return YAML.parse(source);
9
+ };
10
+ export const parseSimfileSource = (source, options = {}) => {
11
+ const raw = parseRawDocument(source, options.path);
12
+ const simfile = simfileSchema.parse(raw);
13
+ const warnings = validateSimfileSemantics(simfile);
14
+ return { simfile, warnings };
15
+ };
@@ -0,0 +1,3 @@
1
+ import { type Simfile } from "./model.js";
2
+ export declare const validateSimfileSemantics: (simfile: Simfile) => string[];
3
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/schema/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAsG7D,eAAO,MAAM,wBAAwB,GAAI,SAAS,OAAO,KAAG,MAAM,EA6DjE,CAAC"}
@@ -0,0 +1,135 @@
1
+ import { simfileEventKinds } from "./model.js";
2
+ const EXPRESSION_IDENTIFIER_PATTERN = /[a-zA-Z_][a-zA-Z0-9_-]*/gu;
3
+ const PLACEHOLDER_PATTERN = /\{([a-z][a-z0-9_-]*)\}/gu;
4
+ const RESERVED_EXPRESSION_NAMES = new Set(["abs", "ceil", "clamp", "cos", "e", "exp", "floor", "lerp", "log", "max", "min", "mod", "pi", "pow", "sin", "smoothstep", "sqrt", "step", "t", "tick"]);
5
+ const SIMFILE_EVENT_KIND_SET = new Set(simfileEventKinds);
6
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7
+ const stringValue = (value) => typeof value === "string" ? value : undefined;
8
+ const validateWhenNode = (node, location, variableIds, phaseIds) => {
9
+ if (!isRecord(node)) {
10
+ throw new Error(`${location} must be a condition object`);
11
+ }
12
+ if ("all" in node) {
13
+ if (!Array.isArray(node.all))
14
+ throw new Error(`${location}.all must be a list`);
15
+ node.all.forEach((child) => validateWhenNode(child, location, variableIds, phaseIds));
16
+ return;
17
+ }
18
+ if ("any" in node) {
19
+ if (!Array.isArray(node.any))
20
+ throw new Error(`${location}.any must be a list`);
21
+ node.any.forEach((child) => validateWhenNode(child, location, variableIds, phaseIds));
22
+ return;
23
+ }
24
+ if ("not" in node) {
25
+ validateWhenNode(node.not, location, variableIds, phaseIds);
26
+ return;
27
+ }
28
+ if ("variable" in node) {
29
+ const variableId = stringValue(node.variable);
30
+ if (variableId === undefined || !variableIds.has(variableId)) {
31
+ throw new Error(`${location} references unknown variable ${String(node.variable)}`);
32
+ }
33
+ return;
34
+ }
35
+ if ("phase" in node) {
36
+ const phaseId = stringValue(node.phase);
37
+ if (phaseId === undefined || !phaseIds.has(phaseId)) {
38
+ throw new Error(`${location} references unknown phase ${String(node.phase)}`);
39
+ }
40
+ return;
41
+ }
42
+ if ("event" in node) {
43
+ const eventKind = stringValue(node.event);
44
+ if (eventKind === undefined || !SIMFILE_EVENT_KIND_SET.has(eventKind)) {
45
+ throw new Error(`${location} references unknown event ${String(node.event)}`);
46
+ }
47
+ }
48
+ };
49
+ const validatePlaceholders = (content, location, variableIds) => {
50
+ for (const match of content.matchAll(PLACEHOLDER_PATTERN)) {
51
+ const variableId = match[1];
52
+ if (!variableIds.has(variableId)) {
53
+ throw new Error(`${location} placeholder references unknown variable ${variableId}`);
54
+ }
55
+ }
56
+ };
57
+ const expressionDependencies = (expression) => {
58
+ const dependencies = new Set();
59
+ for (const match of expression.matchAll(EXPRESSION_IDENTIFIER_PATTERN)) {
60
+ const name = match[0];
61
+ const index = match.index ?? 0;
62
+ const previous = expression[index - 1] ?? "";
63
+ if (/[0-9.]/u.test(previous)) {
64
+ continue;
65
+ }
66
+ const suffix = expression.slice(index + name.length).trimStart();
67
+ if (RESERVED_EXPRESSION_NAMES.has(name) || suffix.startsWith("(")) {
68
+ continue;
69
+ }
70
+ dependencies.add(name);
71
+ }
72
+ return [...dependencies];
73
+ };
74
+ const validateExpressionDependencies = (expression, location, variableIds) => {
75
+ expressionDependencies(expression).forEach((dependency) => {
76
+ if (!variableIds.has(dependency)) {
77
+ throw new Error(`${location} references unknown variable ${dependency}`);
78
+ }
79
+ });
80
+ };
81
+ export const validateSimfileSemantics = (simfile) => {
82
+ const warnings = [];
83
+ const variableIds = new Set(Object.keys(simfile.variables));
84
+ const phaseIds = new Set(Object.keys(simfile.clock.phases));
85
+ const fedVariableIds = new Set(Object.entries(simfile.variables)
86
+ .filter(([, variable]) => variable.fed_by !== undefined)
87
+ .map(([variableId]) => variableId));
88
+ for (const [variableId, variable] of Object.entries(simfile.variables)) {
89
+ if (variable.derive) {
90
+ validateExpressionDependencies(variable.derive.eq, `variable ${variableId} derive.eq`, variableIds);
91
+ }
92
+ }
93
+ for (const [generatorId, generator] of Object.entries(simfile.generators)) {
94
+ if (!variableIds.has(generator.variable)) {
95
+ throw new Error(`generator ${generatorId} references unknown variable ${generator.variable}`);
96
+ }
97
+ if (fedVariableIds.has(generator.variable)) {
98
+ throw new Error(`generator ${generatorId} targets fed variable ${generator.variable}; fed variables have exactly one writer (fed_by)`);
99
+ }
100
+ if (generator.when) {
101
+ validateWhenNode(generator.when, `generator ${generatorId} when`, variableIds, phaseIds);
102
+ }
103
+ if (generator.kind === "deterministic") {
104
+ if (generator.delta_eq) {
105
+ validateExpressionDependencies(generator.delta_eq, `generator ${generatorId} delta_eq`, variableIds);
106
+ }
107
+ if (generator.set_eq) {
108
+ validateExpressionDependencies(generator.set_eq, `generator ${generatorId} set_eq`, variableIds);
109
+ }
110
+ }
111
+ }
112
+ for (const [ruleId, rule] of Object.entries(simfile.rules)) {
113
+ validateWhenNode(rule.when, `rule ${ruleId} when`, variableIds, phaseIds);
114
+ for (const action of rule.do) {
115
+ if ((action.action === "variable:set" || action.action === "variable:delta")
116
+ && !variableIds.has(action.variable)) {
117
+ throw new Error(`rule ${ruleId} action ${action.action} references unknown variable ${action.variable}`);
118
+ }
119
+ if ((action.action === "variable:set" || action.action === "variable:delta")
120
+ && fedVariableIds.has(action.variable)) {
121
+ throw new Error(`rule ${ruleId} action ${action.action} targets fed variable ${action.variable}; fed variables have exactly one writer (fed_by)`);
122
+ }
123
+ if ("content" in action) {
124
+ validatePlaceholders(action.content, `rule ${ruleId} action ${action.action}`, variableIds);
125
+ }
126
+ }
127
+ }
128
+ for (const [probeId, probe] of Object.entries(simfile.probes)) {
129
+ validateWhenNode(probe.when, `probe ${probeId} when`, variableIds, phaseIds);
130
+ if (probe.after) {
131
+ validateWhenNode(probe.after, `probe ${probeId} after`, variableIds, phaseIds);
132
+ }
133
+ }
134
+ return warnings;
135
+ };
@@ -0,0 +1,54 @@
1
+ import { type RunManifestArtifactEntry, type SeedDeclaration, type SimfileRunManifest } from "../observe/manifest.js";
2
+ export declare const sha256HexOfBuffer: (buffer: Buffer) => string;
3
+ /** A type alias (not an interface) so it stays assignable to the manifest's
4
+ * genre-neutral `Record<string, unknown>` world slot. */
5
+ export type ComposeRunManifestWorld = {
6
+ network_id: string;
7
+ room_id: string;
8
+ members: string[];
9
+ };
10
+ export interface ComposeRunManifestInput {
11
+ runId: string;
12
+ /** ISO 8601 timestamp, passed in rather than generated here so the
13
+ * composer stays a pure function of its arguments (deterministic, no
14
+ * hidden `Date.now()` read). */
15
+ createdAt: string;
16
+ /** `spawnfile.up-receipt.v1`'s fingerprint, when available. */
17
+ fingerprint?: string | null;
18
+ /** Disclosed engine kind (Piece 5) — this composed office-sim always runs
19
+ * every agent on the `scripted` engine, so callers pass a single string
20
+ * (e.g. derived by collapsing the up-receipt's `engines[]` to its one
21
+ * distinct value). */
22
+ engine: string;
23
+ /**
24
+ * The run's declared world. A single-network run passes a
25
+ * `ComposeRunManifestWorld` (`{network_id, room_id, members}`); a
26
+ * multi-network composed run (the jungian psyche) passes `{rooms: [...]}`.
27
+ * Stored verbatim on the manifest (the schema's `world` is genre-neutral
28
+ * free-form), so either shape is accepted.
29
+ */
30
+ world: Record<string, unknown>;
31
+ /** `{path, sha256}` entries folded straight from `spawnfile artifacts
32
+ * export --json`'s `index.files` (per that contract's own docstring: "so
33
+ * a future `simfile.run-manifest.v1` can fold `files` straight into its
34
+ * own `artifacts` array ... without re-deriving anything"). */
35
+ exportedArtifacts: readonly RunManifestArtifactEntry[];
36
+ /** Artifacts this driver itself writes after export (e.g.
37
+ * `raw/moltnet/transcript.json`), each already hashed by the caller. */
38
+ extraArtifacts?: readonly RunManifestArtifactEntry[];
39
+ /** Decision-13 ground truth for a doc-seeded memetics secret (memetics
40
+ * increment (a) — the world-driven driver). Omitted for a plain office-sim
41
+ * run, which has no seeded secret. */
42
+ seedDeclaration?: SeedDeclaration;
43
+ }
44
+ /**
45
+ * Writes `simfile.run-manifest.v1` for a composed run (Piece 5 step 3's
46
+ * "writes `manifest.json` LAST" driver step). Pure and deterministic given
47
+ * its inputs: no filesystem, no clock read, no network — artifact hashing
48
+ * happens before this is called, and `createdAt` is threaded in rather than
49
+ * generated here. Artifacts are sorted by path for a stable byte-identical
50
+ * manifest across two structurally-identical runs (the parity gate's
51
+ * determinism check).
52
+ */
53
+ export declare const composeRunManifest: (input: ComposeRunManifestInput) => SimfileRunManifest;
54
+ //# sourceMappingURL=composeRunManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composeRunManifest.d.ts","sourceRoot":"","sources":["../../src/sims/composeRunManifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,wBAAwB,CAAC;AAahC,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,KAAG,MAA2D,CAAC;AAE/G;yDACyD;AACzD,MAAM,MAAM,uBAAuB,GAAG;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd;;oCAEgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;0BAGsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;;;mEAG+D;IAC/D,iBAAiB,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACvD;4EACwE;IACxE,cAAc,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACrD;;0CAEsC;IACtC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,uBAAuB,KAAG,kBAkBnE,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { createHash } from "node:crypto";
2
+ import { RUN_MANIFEST_VERSION } from "../observe/manifest.js";
3
+ import { OBSERVE_REPORT_VERSION } from "../observe/report.js";
4
+ /** The one fixed `contract_versions` map every composed run stamps —
5
+ * mirrors the golden fixture's manifest.json exactly (same three keys, same
6
+ * literal `causal-event.v1` value) so a composed run and the golden capture
7
+ * are structurally comparable. */
8
+ const CONTRACT_VERSIONS = {
9
+ "causal-event.v1": "noopolis.causal-event.v1",
10
+ "simfile.observe.v1": OBSERVE_REPORT_VERSION,
11
+ "simfile.run-manifest.v1": RUN_MANIFEST_VERSION
12
+ };
13
+ export const sha256HexOfBuffer = (buffer) => createHash("sha256").update(buffer).digest("hex");
14
+ /**
15
+ * Writes `simfile.run-manifest.v1` for a composed run (Piece 5 step 3's
16
+ * "writes `manifest.json` LAST" driver step). Pure and deterministic given
17
+ * its inputs: no filesystem, no clock read, no network — artifact hashing
18
+ * happens before this is called, and `createdAt` is threaded in rather than
19
+ * generated here. Artifacts are sorted by path for a stable byte-identical
20
+ * manifest across two structurally-identical runs (the parity gate's
21
+ * determinism check).
22
+ */
23
+ export const composeRunManifest = (input) => {
24
+ const artifacts = [...input.exportedArtifacts, ...(input.extraArtifacts ?? [])]
25
+ .map((artifact) => ({ path: artifact.path, sha256: artifact.sha256 }))
26
+ .sort((left, right) => left.path.localeCompare(right.path));
27
+ return {
28
+ version: RUN_MANIFEST_VERSION,
29
+ run_id: input.runId,
30
+ created_at: input.createdAt,
31
+ contract_versions: CONTRACT_VERSIONS,
32
+ ...(input.fingerprint ? { spawnfile: { fingerprint: input.fingerprint } } : {}),
33
+ artifacts,
34
+ engine: input.engine,
35
+ ...(input.seedDeclaration ? { seed_declaration: input.seedDeclaration } : {}),
36
+ // `SimfileRunManifest.world` is a free-form `Record<string, unknown>`
37
+ // (genre-neutral schema); the driver's world shape is stored verbatim.
38
+ world: input.world
39
+ };
40
+ };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The MULTI-NETWORK composed-run driver: the jungian psyche generalization of
3
+ * `composedOfficeSimDriver.ts`. It runs a recursive Spawnfile org — a psyche
4
+ * floor whose members are self-teams, each owning its OWN inner Moltnet council
5
+ * network — as one composed sim, then assembles a run-dir `simfile observe`
6
+ * reconciles and `simfile view` descends into. Same charter as the office
7
+ * driver: shells `spawnfile up/artifacts export/down --json` only, seeds the
8
+ * floor exactly ONCE, and every other step is a read-only poll. The interior
9
+ * deliberation (representative -> inner council -> back to the floor) is driven
10
+ * entirely by the agents' own wake-across-membranes plumbing, never coaxed
11
+ * here.
12
+ */
13
+ export interface RunComposedJungianSimOptions {
14
+ spawnfileBin: string;
15
+ /** Path to the composed jungian org (`fixtures/sims/jungian-daimon-org/org`). */
16
+ orgPath: string;
17
+ containerName: string;
18
+ deploymentName: string;
19
+ /** Scratch dir for spawnfile's compile output + deployment record — the compile report is read from here. */
20
+ compiledOutputDirectory: string;
21
+ /** Parent directory under which `runs/<run_id>/` is assembled. */
22
+ runsRootDirectory: string;
23
+ /** The floor network the operator seed is posted into. */
24
+ seedNetworkId?: string;
25
+ seedRoomId?: string;
26
+ /** The representative agent the seed @mentions to wake it. */
27
+ seedTargetAgentId?: string;
28
+ seedMessageText?: string;
29
+ /** Substring the representative's floor-facing SYNTHESIS carries — the run's completion gate. */
30
+ synthesisMarker?: string;
31
+ timeoutMs?: number;
32
+ pollIntervalMs?: number;
33
+ removeVolumesOnDown?: boolean;
34
+ now?: () => Date;
35
+ }
36
+ export interface RunComposedJungianSimResult {
37
+ runDir: string;
38
+ runId: string;
39
+ /** The representative's floor-facing synthesis message text (proof the whole membrane chain closed). */
40
+ synthesis: string;
41
+ }
42
+ /**
43
+ * Runs the composed jungian psyche end to end: up -> poll every network ready
44
+ * -> seed the floor ONCE -> wait for the representative's synthesis to reappear
45
+ * on the floor (proof the interior council deliberated and answered across the
46
+ * membrane) -> export per-network transcripts + causal artifacts + the compile
47
+ * report -> down -> write `manifest.json` (with `world.rooms[]`) LAST.
48
+ */
49
+ export declare const runComposedJungianSim: (options: RunComposedJungianSimOptions) => Promise<RunComposedJungianSimResult>;
50
+ //# sourceMappingURL=composedJungianSimDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composedJungianSimDriver.d.ts","sourceRoot":"","sources":["../../src/sims/composedJungianSimDriver.ts"],"names":[],"mappings":"AA2BA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,6GAA6G;IAC7G,uBAAuB,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,wGAAwG;IACxG,SAAS,EAAE,MAAM,CAAC;CACnB;AAsHD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAChC,SAAS,4BAA4B,KACpC,OAAO,CAAC,2BAA2B,CA2GrC,CAAC"}