synai-simulator 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.
package/README.md ADDED
Binary file
@@ -0,0 +1,87 @@
1
+ type TaskStatus = "queued" | "running" | "completed" | "failed";
2
+ type TaskPhase = "cpu" | "io";
3
+ type ResourceCurve = {
4
+ base: number;
5
+ peak: number;
6
+ variance: number;
7
+ };
8
+ type FailureType = "pressure" | "timeout" | "starvation" | "load_shed" | "random";
9
+ type ExecutionProfile = {
10
+ meanDuration: number;
11
+ cpuCurve: ResourceCurve;
12
+ ramCurve: ResourceCurve;
13
+ };
14
+ type Task = {
15
+ id: string;
16
+ value: number;
17
+ deadline: number;
18
+ execution: ExecutionProfile;
19
+ createdAt: number;
20
+ startedAt?: number;
21
+ expectedEndAt?: number;
22
+ progress: number;
23
+ phase: TaskPhase;
24
+ jitter?: number;
25
+ currentRAM?: number;
26
+ failureProbability: number;
27
+ failureReason?: string;
28
+ failureType?: FailureType;
29
+ maxQueueTime?: number;
30
+ status: TaskStatus;
31
+ };
32
+
33
+ type Worker = {
34
+ id: string;
35
+ maxCPU: number;
36
+ maxRAM: number;
37
+ usedCPU: number;
38
+ usedRAM: number;
39
+ activeTaskIds: string[];
40
+ online: boolean;
41
+ };
42
+
43
+ type SystemResources = {
44
+ totalCPU: number;
45
+ totalRAM: number;
46
+ };
47
+
48
+ type SystemMetrics = {
49
+ queueLength: number;
50
+ cpuPressure: number;
51
+ ramPressure: number;
52
+ pressure: number;
53
+ completed: number;
54
+ failed: number;
55
+ stabilityIndex: number;
56
+ };
57
+
58
+ type PolicyName = "FAIRNESS" | "BALANCED" | "THROUGHPUT";
59
+ type Policy = {
60
+ starvationWeight: number;
61
+ latenessWeight: number;
62
+ failureWeight: number;
63
+ instabilityWeight: number;
64
+ };
65
+ declare const POLICIES: Record<PolicyName, Policy>;
66
+
67
+ interface SystemConfig {
68
+ maxConcurrentTasks: number;
69
+ }
70
+ type SystemState = {
71
+ time: number;
72
+ policy: PolicyName;
73
+ resources: SystemResources;
74
+ config: SystemConfig;
75
+ tasks: Task[];
76
+ workers: Worker[];
77
+ metrics: SystemMetrics;
78
+ };
79
+
80
+ type RNG = () => number;
81
+ declare function createRNG(seed: number): RNG;
82
+
83
+ declare function tick(state: SystemState, dt: number, rng: RNG): SystemState;
84
+
85
+ declare function computeMetrics(state: SystemState): SystemState;
86
+
87
+ export { type ExecutionProfile, type FailureType, POLICIES, type Policy, type PolicyName, type RNG, type ResourceCurve, type SystemConfig, type SystemMetrics, type SystemResources, type SystemState, type Task, type TaskPhase, type TaskStatus, computeMetrics, createRNG, tick };
package/dist/index.js ADDED
@@ -0,0 +1,377 @@
1
+ // src/engine/policy.ts
2
+ var POLICIES = {
3
+ FAIRNESS: {
4
+ starvationWeight: 2,
5
+ latenessWeight: 0.8,
6
+ failureWeight: 1,
7
+ instabilityWeight: 0.5
8
+ },
9
+ BALANCED: {
10
+ starvationWeight: 0.5,
11
+ latenessWeight: 1,
12
+ failureWeight: 2,
13
+ instabilityWeight: 1
14
+ },
15
+ THROUGHPUT: {
16
+ starvationWeight: 0.1,
17
+ latenessWeight: 1.5,
18
+ failureWeight: 3,
19
+ instabilityWeight: 2
20
+ }
21
+ };
22
+
23
+ // src/engine/random.ts
24
+ function createRNG(seed) {
25
+ let t = seed >>> 0;
26
+ return function() {
27
+ t += 1831565813;
28
+ let r = Math.imul(t ^ t >>> 15, 1 | t);
29
+ r ^= r + Math.imul(r ^ r >>> 7, 61 | r);
30
+ return ((r ^ r >>> 14) >>> 0) / 4294967296;
31
+ };
32
+ }
33
+
34
+ // src/engine/metrics.ts
35
+ function computeMetrics(state2) {
36
+ let usedCPU = 0;
37
+ let usedRAM = 0;
38
+ for (const task of state2.tasks) {
39
+ if (task.status === "running") {
40
+ usedCPU += task.execution.cpuCurve.base;
41
+ usedRAM += task.execution.ramCurve.base;
42
+ }
43
+ }
44
+ const cpuPressure = usedCPU / state2.resources.totalCPU;
45
+ const ramPressure = usedRAM / state2.resources.totalRAM;
46
+ const pressure = Math.max(cpuPressure, ramPressure);
47
+ const queueLength = state2.tasks.filter((t) => t.status === "queued").length;
48
+ const failed = state2.tasks.filter((t) => t.status === "failed").length;
49
+ const pressurePenalty = Math.min(pressure * 50, 60);
50
+ const queuePenalty = Math.min(queueLength * 3, 25);
51
+ const failurePenalty = Math.min(failed * 5, 40);
52
+ const stabilityIndex = Math.max(
53
+ 0,
54
+ Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)
55
+ );
56
+ state2.metrics = {
57
+ ...state2.metrics,
58
+ cpuPressure,
59
+ ramPressure,
60
+ pressure,
61
+ queueLength,
62
+ completed: state2.tasks.filter((t) => t.status === "completed").length,
63
+ failed,
64
+ stabilityIndex
65
+ };
66
+ return state2;
67
+ }
68
+
69
+ // src/engine/cost.ts
70
+ function computeTaskCost(task, state2) {
71
+ const policy = POLICIES[state2.policy];
72
+ const now = state2.time;
73
+ const pressure = state2.metrics.pressure;
74
+ const waitingTime = task.startedAt === void 0 ? now - task.createdAt : 0;
75
+ const starvation = waitingTime * policy.starvationWeight;
76
+ const latenessTime = Math.max(0, now - task.deadline);
77
+ const lateness = latenessTime * policy.latenessWeight;
78
+ const failureRisk = task.failureProbability * pressure * policy.failureWeight;
79
+ const instability = pressure * pressure * policy.instabilityWeight;
80
+ const total = starvation + lateness + failureRisk + instability;
81
+ return {
82
+ starvation,
83
+ lateness,
84
+ failureRisk,
85
+ instability,
86
+ total
87
+ };
88
+ }
89
+
90
+ // src/engine/execution.ts
91
+ function sampleUsage(curve, rng2) {
92
+ const spread = curve.peak - curve.base;
93
+ const noise = (rng2() - 0.5) * 2;
94
+ const usage = curve.base + spread * curve.variance * noise;
95
+ return Math.max(0, usage);
96
+ }
97
+ function slowdownFactor(pressure) {
98
+ return 1 + pressure * pressure;
99
+ }
100
+
101
+ // src/engine/scheduler.ts
102
+ var MAX_PRESSURE = 1.2;
103
+ function phaseFailureMultiplier(phase) {
104
+ return phase === "io" ? 1.6 : 1;
105
+ }
106
+ function schedule(state2, dt, rng2) {
107
+ const now = state2.time;
108
+ for (const t of state2.tasks) {
109
+ if (t.status === "queued" && t.maxQueueTime !== void 0 && now - t.createdAt > t.maxQueueTime && state2.metrics.pressure > 1) {
110
+ t.status = "failed";
111
+ t.failureType = "starvation";
112
+ t.failureReason = "Starvation: task waited too long in queue under pressure";
113
+ }
114
+ }
115
+ const queued = state2.tasks.filter((t) => t.status === "queued");
116
+ if (state2.metrics.pressure > MAX_PRESSURE && queued.length > 0) {
117
+ const worst = queued.map((t) => ({ t, cost: computeTaskCost(t, state2).total })).sort((a, b) => b.cost - a.cost)[0].t;
118
+ worst.status = "failed";
119
+ worst.failureType = "load_shed";
120
+ worst.failureReason = "Load shed: system pressure exceeded safe threshold";
121
+ }
122
+ const queuedWithCost = state2.tasks.filter((t) => t.status === "queued").map((t) => ({ t, cost: computeTaskCost(t, state2).total }));
123
+ let sortedQueued;
124
+ switch (state2.policy) {
125
+ case "THROUGHPUT":
126
+ sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);
127
+ break;
128
+ case "FAIRNESS":
129
+ sortedQueued = queuedWithCost.sort(
130
+ (a, b) => a.t.createdAt - b.t.createdAt
131
+ );
132
+ break;
133
+ case "BALANCED":
134
+ default:
135
+ sortedQueued = queuedWithCost.sort(
136
+ (a, b) => 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)
137
+ );
138
+ }
139
+ let runningCount = state2.tasks.filter((t) => t.status === "running").length;
140
+ for (const { t } of sortedQueued) {
141
+ if (runningCount >= state2.config.maxConcurrentTasks) break;
142
+ t.status = "running";
143
+ t.startedAt = now;
144
+ t.expectedEndAt = now + t.execution.meanDuration;
145
+ t.currentRAM = sampleUsage(t.execution.ramCurve, rng2);
146
+ runningCount++;
147
+ }
148
+ const running = state2.tasks.filter((t) => t.status === "running");
149
+ const cpuTasks = running.filter((t) => t.phase === "cpu");
150
+ const cpuPerTask = cpuTasks.length > 0 ? state2.resources.totalCPU / cpuTasks.length : 0;
151
+ let totalUsedRAM = 0;
152
+ for (const t of running) {
153
+ if (t.currentRAM !== void 0) {
154
+ totalUsedRAM += t.currentRAM;
155
+ }
156
+ }
157
+ state2.metrics.ramPressure = totalUsedRAM / state2.resources.totalRAM;
158
+ for (const t of running) {
159
+ const cpuSlow = slowdownFactor(state2.metrics.cpuPressure);
160
+ if (t.phase === "cpu") {
161
+ t.progress += cpuPerTask / state2.resources.totalCPU * (dt / t.execution.meanDuration) / cpuSlow;
162
+ } else {
163
+ const ramSlow = 1 + Math.max(0, state2.metrics.ramPressure - 1);
164
+ t.progress += 0.3 * dt / t.execution.meanDuration / ramSlow;
165
+ }
166
+ if (t.deadline !== void 0 && t.startedAt !== void 0) {
167
+ const effectiveDeadline = t.deadline * Math.max(1, state2.metrics.pressure);
168
+ if (now - t.startedAt > effectiveDeadline && state2.metrics.pressure > 1) {
169
+ t.status = "failed";
170
+ t.failureType = "timeout";
171
+ t.failureReason = "Deadline exceeded under sustained pressure";
172
+ continue;
173
+ }
174
+ }
175
+ const runTime = t.startedAt !== void 0 ? now - t.startedAt : 0;
176
+ const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);
177
+ const lambda = t.failureProbability * phaseFailureMultiplier(t.phase) * fatigueMultiplier * state2.metrics.pressure;
178
+ const perTickRisk = 1 - Math.exp(-lambda * dt);
179
+ if (rng2() < perTickRisk) {
180
+ t.status = "failed";
181
+ t.failureType = "pressure";
182
+ t.failureReason = `Execution failure (\u03BB=${lambda.toFixed(3)})`;
183
+ continue;
184
+ }
185
+ if (t.progress >= 1) {
186
+ t.status = "completed";
187
+ }
188
+ if (rng2() < 0.15) {
189
+ t.phase = t.phase === "cpu" ? "io" : "cpu";
190
+ }
191
+ }
192
+ return state2;
193
+ }
194
+
195
+ // src/engine/tick.ts
196
+ function tick(state2, dt, rng2) {
197
+ let next = { ...state2, time: state2.time + dt };
198
+ next = computeMetrics(next);
199
+ next = schedule(next, dt, rng2);
200
+ next = computeMetrics(next);
201
+ return next;
202
+ }
203
+
204
+ // src/worker/simulator.worker.ts
205
+ console.log("\u{1F525} WORKER FILE EXECUTED");
206
+ var currentSeed = 1;
207
+ var rng = createRNG(currentSeed);
208
+ var state = null;
209
+ var interval = null;
210
+ var TICK_MS = 100;
211
+ var sustainedPressureTicks = 0;
212
+ var COLLAPSE_PRESSURE = 1.5;
213
+ var COLLAPSE_TICKS = 10;
214
+ var eventLog = [];
215
+ self.onmessage = (event) => {
216
+ const msg = event.data;
217
+ if (state && !["STATE", "INIT"].includes(msg.type)) {
218
+ eventLog.push({
219
+ time: state.time,
220
+ message: msg
221
+ });
222
+ }
223
+ switch (msg.type) {
224
+ case "INIT": {
225
+ state = structuredClone(msg.payload.state);
226
+ initialSnapshot = structuredClone(msg.payload.state);
227
+ currentSeed = msg.payload.seed ?? 1;
228
+ rng = createRNG(currentSeed);
229
+ eventLog = [];
230
+ sustainedPressureTicks = 0;
231
+ post();
232
+ break;
233
+ }
234
+ case "START": {
235
+ if (!state || interval !== null) return;
236
+ interval = setInterval(runTick, TICK_MS);
237
+ break;
238
+ }
239
+ case "PAUSE": {
240
+ if (interval !== null) {
241
+ clearInterval(interval);
242
+ interval = null;
243
+ }
244
+ break;
245
+ }
246
+ case "STEP": {
247
+ runTick();
248
+ break;
249
+ }
250
+ case "SET_CONFIG": {
251
+ if (!state) return;
252
+ state.config = {
253
+ ...state.config,
254
+ ...msg.payload
255
+ };
256
+ post();
257
+ break;
258
+ }
259
+ case "ADD_TASK": {
260
+ if (!state) return;
261
+ state.tasks.push({
262
+ ...msg.payload,
263
+ createdAt: state.time
264
+ });
265
+ break;
266
+ }
267
+ case "SET_POLICY": {
268
+ if (!state) return;
269
+ state.policy = msg.payload;
270
+ break;
271
+ }
272
+ case "SET_RESOURCES": {
273
+ if (!state) return;
274
+ state.resources = {
275
+ ...state.resources,
276
+ ...msg.payload
277
+ };
278
+ for (const w of state.workers) {
279
+ w.maxCPU = state.resources.totalCPU;
280
+ w.maxRAM = state.resources.totalRAM;
281
+ }
282
+ post();
283
+ break;
284
+ }
285
+ case "EXPORT_REPLAY": {
286
+ postMessage({
287
+ type: "REPLAY_DATA",
288
+ payload: {
289
+ seed: currentSeed,
290
+ events: eventLog
291
+ }
292
+ });
293
+ break;
294
+ }
295
+ case "REPLAY": {
296
+ if (!initialSnapshot) return;
297
+ state = structuredClone(initialSnapshot);
298
+ rng = createRNG(msg.payload.seed);
299
+ sustainedPressureTicks = 0;
300
+ for (const e of msg.payload.events) {
301
+ applyEvent(e.message);
302
+ }
303
+ post();
304
+ break;
305
+ }
306
+ }
307
+ };
308
+ function runTick() {
309
+ if (!state) return;
310
+ state = tick(state, TICK_MS / 1e3, rng);
311
+ if (state.metrics.pressure > COLLAPSE_PRESSURE) {
312
+ sustainedPressureTicks++;
313
+ } else {
314
+ sustainedPressureTicks = 0;
315
+ }
316
+ if (state.metrics.stabilityIndex <= 15 || sustainedPressureTicks >= COLLAPSE_TICKS) {
317
+ postMessage({
318
+ type: "COLLAPSE",
319
+ payload: {
320
+ time: state.time,
321
+ stabilityIndex: state.metrics.stabilityIndex,
322
+ pressure: state.metrics.pressure,
323
+ reason: sustainedPressureTicks >= COLLAPSE_TICKS ? "Sustained system pressure" : "System stability degraded beyond recovery"
324
+ }
325
+ });
326
+ clearInterval(interval);
327
+ interval = null;
328
+ return;
329
+ }
330
+ post();
331
+ }
332
+ function post() {
333
+ postMessage({
334
+ type: "STATE",
335
+ payload: state
336
+ });
337
+ }
338
+ var initialSnapshot = null;
339
+ function applyEvent(msg) {
340
+ switch (msg.type) {
341
+ case "ADD_TASK":
342
+ state?.tasks.push({
343
+ ...msg.payload,
344
+ createdAt: state.time
345
+ });
346
+ break;
347
+ case "SET_POLICY":
348
+ if (state) state.policy = msg.payload;
349
+ break;
350
+ case "SET_RESOURCES":
351
+ if (state) {
352
+ state.resources = {
353
+ ...state.resources,
354
+ ...msg.payload
355
+ };
356
+ }
357
+ break;
358
+ case "START":
359
+ if (!interval) {
360
+ interval = setInterval(runTick, TICK_MS);
361
+ }
362
+ break;
363
+ case "PAUSE":
364
+ if (interval) {
365
+ clearInterval(interval);
366
+ interval = null;
367
+ }
368
+ break;
369
+ }
370
+ }
371
+ export {
372
+ POLICIES,
373
+ computeMetrics,
374
+ createRNG,
375
+ tick
376
+ };
377
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/policy.ts","../src/engine/random.ts","../src/engine/metrics.ts","../src/engine/cost.ts","../src/engine/execution.ts","../src/engine/scheduler.ts","../src/engine/tick.ts","../src/worker/simulator.worker.ts"],"sourcesContent":["export type PolicyName = \"FAIRNESS\" | \"BALANCED\" | \"THROUGHPUT\";\r\n\r\nexport type Policy = {\r\n starvationWeight: number;\r\n latenessWeight: number;\r\n failureWeight: number;\r\n instabilityWeight: number;\r\n};\r\n\r\nexport const POLICIES: Record<PolicyName, Policy> = {\r\n FAIRNESS: {\r\n starvationWeight: 2,\r\n latenessWeight: 0.8,\r\n failureWeight: 1,\r\n instabilityWeight: 0.5,\r\n },\r\n BALANCED: {\r\n starvationWeight: 0.5,\r\n latenessWeight: 1,\r\n failureWeight: 2,\r\n instabilityWeight: 1,\r\n },\r\n THROUGHPUT: {\r\n starvationWeight: 0.1,\r\n latenessWeight: 1.5,\r\n failureWeight: 3,\r\n instabilityWeight: 2,\r\n },\r\n};\r\n","export type RNG = () => number;\r\n\r\nexport function createRNG(seed: number): RNG {\r\n let t = seed >>> 0;\r\n\r\n return function () {\r\n t += 0x6d2b79f5;\r\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\r\n r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);\r\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n","import { SystemState } from \"../core/state\";\r\n\r\nexport function computeMetrics(state: SystemState): SystemState {\r\n let usedCPU = 0;\r\n let usedRAM = 0;\r\n\r\n for (const task of state.tasks) {\r\n if (task.status === \"running\") {\r\n usedCPU += task.execution.cpuCurve.base;\r\n usedRAM += task.execution.ramCurve.base;\r\n }\r\n }\r\n\r\n const cpuPressure = usedCPU / state.resources.totalCPU;\r\n const ramPressure = usedRAM / state.resources.totalRAM;\r\n const pressure = Math.max(cpuPressure, ramPressure);\r\n\r\n const queueLength = state.tasks.filter((t) => t.status === \"queued\").length;\r\n\r\n const failed = state.tasks.filter((t) => t.status === \"failed\").length;\r\n\r\n // 🔥 System Stability Index (0–100)\r\n const pressurePenalty = Math.min(pressure * 50, 60);\r\n const queuePenalty = Math.min(queueLength * 3, 25);\r\n const failurePenalty = Math.min(failed * 5, 40);\r\n\r\n const stabilityIndex = Math.max(\r\n 0,\r\n Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)\r\n );\r\n\r\n state.metrics = {\r\n ...state.metrics,\r\n cpuPressure,\r\n ramPressure,\r\n pressure,\r\n queueLength,\r\n completed: state.tasks.filter((t) => t.status === \"completed\").length,\r\n failed,\r\n stabilityIndex,\r\n };\r\n\r\n return state;\r\n}\r\n","import { Task } from \"../core/task\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { POLICIES } from \"./policy\";\r\n\r\nexport type CostBreakdown = {\r\n starvation: number;\r\n lateness: number;\r\n failureRisk: number;\r\n instability: number;\r\n total: number;\r\n};\r\n\r\nexport function computeTaskCost(task: Task, state: SystemState): CostBreakdown {\r\n const policy = POLICIES[state.policy];\r\n const now = state.time;\r\n const pressure = state.metrics.pressure;\r\n\r\n // --- Starvation ---\r\n const waitingTime = task.startedAt === undefined ? now - task.createdAt : 0;\r\n\r\n const starvation = waitingTime * policy.starvationWeight;\r\n\r\n // --- Lateness ---\r\n const latenessTime = Math.max(0, now - task.deadline);\r\n\r\n const lateness = latenessTime * policy.latenessWeight;\r\n\r\n // --- Failure Risk (expected loss) ---\r\n const failureRisk = task.failureProbability * pressure * policy.failureWeight;\r\n\r\n // --- System Instability ---\r\n const instability = pressure * pressure * policy.instabilityWeight;\r\n\r\n const total = starvation + lateness + failureRisk + instability;\r\n\r\n return {\r\n starvation,\r\n lateness,\r\n failureRisk,\r\n instability,\r\n total,\r\n };\r\n}\r\n","import { ResourceCurve } from \"../core/task\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function sampleUsage(curve: ResourceCurve, rng: RNG): number {\r\n const spread = curve.peak - curve.base;\r\n\r\n // centered noise in [-0.5, 0.5]\r\n const noise = (rng() - 0.5) * 2;\r\n\r\n const usage = curve.base + spread * curve.variance * noise;\r\n\r\n return Math.max(0, usage);\r\n}\r\n\r\nexport function slowdownFactor(pressure: number): number {\r\n return 1 + pressure * pressure;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeTaskCost } from \"./cost\";\r\nimport { slowdownFactor } from \"./execution\";\r\nimport { RNG } from \"./random\";\r\nimport { sampleUsage } from \"./execution\";\r\n\r\nconst MAX_PRESSURE = 1.2;\r\n\r\nfunction phaseFailureMultiplier(phase: \"cpu\" | \"io\") {\r\n return phase === \"io\" ? 1.6 : 1.0;\r\n}\r\n\r\nexport function schedule(\r\n state: SystemState,\r\n dt: number,\r\n rng: RNG\r\n): SystemState {\r\n const now = state.time;\r\n\r\n /* =========================================================\r\n 1. STARVATION FAILURE (queued too long, under pressure)\r\n ========================================================= */\r\n\r\n for (const t of state.tasks) {\r\n if (\r\n t.status === \"queued\" &&\r\n t.maxQueueTime !== undefined &&\r\n now - t.createdAt > t.maxQueueTime &&\r\n state.metrics.pressure > 1\r\n ) {\r\n t.status = \"failed\";\r\n t.failureType = \"starvation\";\r\n t.failureReason =\r\n \"Starvation: task waited too long in queue under pressure\";\r\n }\r\n }\r\n\r\n const queued = state.tasks.filter((t) => t.status === \"queued\");\r\n\r\n /* =========================================================\r\n 2. LOAD SHEDDING (system protection)\r\n ========================================================= */\r\n\r\n if (state.metrics.pressure > MAX_PRESSURE && queued.length > 0) {\r\n const worst = queued\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }))\r\n .sort((a, b) => b.cost - a.cost)[0].t;\r\n\r\n worst.status = \"failed\";\r\n worst.failureType = \"load_shed\";\r\n worst.failureReason = \"Load shed: system pressure exceeded safe threshold\";\r\n }\r\n\r\n /* =========================================================\r\n 3. ADMISSION CONTROL (concurrency-limited)\r\n ========================================================= */\r\n\r\n const queuedWithCost = state.tasks\r\n .filter((t) => t.status === \"queued\")\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }));\r\n\r\n let sortedQueued;\r\n\r\n switch (state.policy) {\r\n case \"THROUGHPUT\":\r\n // favor cheap tasks → maximize completions\r\n sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);\r\n break;\r\n\r\n case \"FAIRNESS\":\r\n // favor oldest tasks\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) => a.t.createdAt - b.t.createdAt\r\n );\r\n break;\r\n\r\n case \"BALANCED\":\r\n default:\r\n // mix age + cost\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) =>\r\n 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)\r\n );\r\n }\r\n\r\n let runningCount = state.tasks.filter((t) => t.status === \"running\").length;\r\n\r\n for (const { t } of sortedQueued) {\r\n if (runningCount >= state.config.maxConcurrentTasks) break;\r\n\r\n t.status = \"running\";\r\n t.startedAt = now;\r\n t.expectedEndAt = now + t.execution.meanDuration;\r\n\r\n t.currentRAM = sampleUsage(t.execution.ramCurve, rng);\r\n\r\n runningCount++;\r\n }\r\n\r\n /* =========================================================\r\n 4. EXECUTE RUNNING TASKS\r\n ========================================================= */\r\n\r\n const running = state.tasks.filter((t) => t.status === \"running\");\r\n\r\n /* ---------- CPU SHARING ---------- */\r\n const cpuTasks = running.filter((t) => t.phase === \"cpu\");\r\n const cpuPerTask =\r\n cpuTasks.length > 0 ? state.resources.totalCPU / cpuTasks.length : 0;\r\n\r\n /* ---------- RAM ACCUMULATION ---------- */\r\n let totalUsedRAM = 0;\r\n for (const t of running) {\r\n if (t.currentRAM !== undefined) {\r\n totalUsedRAM += t.currentRAM;\r\n }\r\n }\r\n\r\n state.metrics.ramPressure = totalUsedRAM / state.resources.totalRAM;\r\n\r\n /* ---------- EXECUTION LOOP ---------- */\r\n for (const t of running) {\r\n const cpuSlow = slowdownFactor(state.metrics.cpuPressure);\r\n\r\n if (t.phase === \"cpu\") {\r\n t.progress +=\r\n ((cpuPerTask / state.resources.totalCPU) *\r\n (dt / t.execution.meanDuration)) /\r\n cpuSlow;\r\n } else {\r\n const ramSlow = 1 + Math.max(0, state.metrics.ramPressure - 1);\r\n\r\n t.progress += (0.3 * dt) / t.execution.meanDuration / ramSlow;\r\n }\r\n\r\n /* ---------- TIMEOUT FAILURE ---------- */\r\n if (t.deadline !== undefined && t.startedAt !== undefined) {\r\n const effectiveDeadline =\r\n t.deadline * Math.max(1, state.metrics.pressure);\r\n\r\n if (now - t.startedAt > effectiveDeadline && state.metrics.pressure > 1) {\r\n t.status = \"failed\";\r\n t.failureType = \"timeout\";\r\n t.failureReason = \"Deadline exceeded under sustained pressure\";\r\n continue;\r\n }\r\n }\r\n\r\n /* ---------- PRESSURE-CORRELATED FAILURE ---------- */\r\n const runTime = t.startedAt !== undefined ? now - t.startedAt : 0;\r\n\r\n const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);\r\n\r\n const lambda =\r\n t.failureProbability *\r\n phaseFailureMultiplier(t.phase) *\r\n fatigueMultiplier *\r\n state.metrics.pressure;\r\n\r\n const perTickRisk = 1 - Math.exp(-lambda * dt);\r\n\r\n if (rng() < perTickRisk) {\r\n t.status = \"failed\";\r\n t.failureType = \"pressure\";\r\n t.failureReason = `Execution failure (λ=${lambda.toFixed(3)})`;\r\n continue;\r\n }\r\n\r\n /* ---------- COMPLETION ---------- */\r\n if (t.progress >= 1) {\r\n t.status = \"completed\";\r\n }\r\n\r\n /* ---------- ASYNC ILLUSION ---------- */\r\n if (rng() < 0.15) {\r\n t.phase = t.phase === \"cpu\" ? \"io\" : \"cpu\";\r\n }\r\n }\r\n\r\n return state;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeMetrics } from \"./metrics\";\r\nimport { schedule } from \"./scheduler\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function tick(state: SystemState, dt: number, rng: RNG): SystemState {\r\n let next = { ...state, time: state.time + dt };\r\n\r\n next = computeMetrics(next);\r\n next = schedule(next, dt, rng);\r\n next = computeMetrics(next);\r\n\r\n return next;\r\n}\r\n","/// <reference lib=\"webworker\" />\r\nconsole.log(\"🔥 WORKER FILE EXECUTED\");\r\nimport { tick } from \"../engine/tick\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { Task } from \"../core/task\";\r\nimport { PolicyName } from \"../engine/policy\";\r\nimport { SystemResources } from \"../core/resources\";\r\nimport { createRNG } from \"../engine/random\";\r\nlet currentSeed: number = 1;\r\nlet rng = createRNG(currentSeed);\r\n\r\nlet state: SystemState | null = null;\r\nlet interval: ReturnType<typeof setInterval> | null = null;\r\n\r\nconst TICK_MS = 100;\r\nlet sustainedPressureTicks = 0;\r\nconst COLLAPSE_PRESSURE = 1.5;\r\nconst COLLAPSE_TICKS = 10;\r\n\r\nlet eventLog: Array<{\r\n time: number;\r\n message: any;\r\n}> = [];\r\n\r\nself.onmessage = (event: MessageEvent) => {\r\n const msg = event.data;\r\n // Log user actions (but NOT INIT or STATE)\r\n if (state && ![\"STATE\", \"INIT\"].includes(msg.type)) {\r\n eventLog.push({\r\n time: state.time,\r\n message: msg,\r\n });\r\n }\r\n switch (msg.type) {\r\n case \"INIT\": {\r\n state = structuredClone(msg.payload.state);\r\n initialSnapshot = structuredClone(msg.payload.state);\r\n currentSeed = msg.payload.seed ?? 1;\r\n rng = createRNG(currentSeed);\r\n eventLog = [];\r\n sustainedPressureTicks = 0;\r\n post();\r\n break;\r\n }\r\n\r\n case \"START\": {\r\n if (!state || interval !== null) return;\r\n interval = setInterval(runTick, TICK_MS);\r\n break;\r\n }\r\n\r\n case \"PAUSE\": {\r\n if (interval !== null) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n\r\n case \"STEP\": {\r\n runTick();\r\n break;\r\n }\r\n case \"SET_CONFIG\": {\r\n if (!state) return;\r\n\r\n state.config = {\r\n ...state.config,\r\n ...msg.payload,\r\n };\r\n\r\n post();\r\n break;\r\n }\r\n case \"ADD_TASK\": {\r\n if (!state) return;\r\n\r\n state.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n\r\n break;\r\n }\r\n\r\n case \"SET_POLICY\": {\r\n if (!state) return;\r\n state.policy = msg.payload as PolicyName;\r\n break;\r\n }\r\n\r\n case \"SET_RESOURCES\": {\r\n if (!state) return;\r\n state.resources = {\r\n ...state.resources,\r\n ...(msg.payload as Partial<SystemResources>),\r\n };\r\n for (const w of state.workers) {\r\n w.maxCPU = state.resources.totalCPU;\r\n w.maxRAM = state.resources.totalRAM;\r\n }\r\n post();\r\n break;\r\n }\r\n case \"EXPORT_REPLAY\": {\r\n postMessage({\r\n type: \"REPLAY_DATA\",\r\n payload: {\r\n seed: currentSeed,\r\n events: eventLog,\r\n },\r\n });\r\n break;\r\n }\r\n\r\n case \"REPLAY\": {\r\n if (!initialSnapshot) return;\r\n\r\n // Reset system\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(msg.payload.seed);\r\n sustainedPressureTicks = 0;\r\n\r\n // Re-apply events deterministically\r\n for (const e of msg.payload.events) {\r\n applyEvent(e.message);\r\n }\r\n\r\n post();\r\n break;\r\n }\r\n }\r\n};\r\n\r\nfunction runTick() {\r\n if (!state) return;\r\n\r\n state = tick(state, TICK_MS / 1000, rng);\r\n\r\n if (state.metrics.pressure > COLLAPSE_PRESSURE) {\r\n sustainedPressureTicks++;\r\n } else {\r\n sustainedPressureTicks = 0;\r\n }\r\n\r\n if (\r\n state.metrics.stabilityIndex <= 15 ||\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ) {\r\n postMessage({\r\n type: \"COLLAPSE\",\r\n payload: {\r\n time: state.time,\r\n stabilityIndex: state.metrics.stabilityIndex,\r\n pressure: state.metrics.pressure,\r\n reason:\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ? \"Sustained system pressure\"\r\n : \"System stability degraded beyond recovery\",\r\n },\r\n });\r\n\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n post();\r\n}\r\n\r\nfunction post() {\r\n postMessage({\r\n type: \"STATE\",\r\n payload: state,\r\n });\r\n}\r\n\r\nlet initialSnapshot: SystemState | null = null;\r\n\r\nfunction reset() {\r\n if (!initialSnapshot) return;\r\n\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(currentSeed);\r\n}\r\n\r\nfunction applyEvent(msg: any) {\r\n switch (msg.type) {\r\n case \"ADD_TASK\":\r\n state?.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n break;\r\n\r\n case \"SET_POLICY\":\r\n if (state) state.policy = msg.payload;\r\n break;\r\n\r\n case \"SET_RESOURCES\":\r\n if (state) {\r\n state.resources = {\r\n ...state.resources,\r\n ...msg.payload,\r\n };\r\n }\r\n break;\r\n\r\n case \"START\":\r\n if (!interval) {\r\n interval = setInterval(runTick, TICK_MS);\r\n }\r\n break;\r\n\r\n case \"PAUSE\":\r\n if (interval) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n}\r\n"],"mappings":"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","names":["state","state","rng","state","rng","state","rng"]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/worker.js ADDED
@@ -0,0 +1,371 @@
1
+ // src/engine/metrics.ts
2
+ function computeMetrics(state2) {
3
+ let usedCPU = 0;
4
+ let usedRAM = 0;
5
+ for (const task of state2.tasks) {
6
+ if (task.status === "running") {
7
+ usedCPU += task.execution.cpuCurve.base;
8
+ usedRAM += task.execution.ramCurve.base;
9
+ }
10
+ }
11
+ const cpuPressure = usedCPU / state2.resources.totalCPU;
12
+ const ramPressure = usedRAM / state2.resources.totalRAM;
13
+ const pressure = Math.max(cpuPressure, ramPressure);
14
+ const queueLength = state2.tasks.filter((t) => t.status === "queued").length;
15
+ const failed = state2.tasks.filter((t) => t.status === "failed").length;
16
+ const pressurePenalty = Math.min(pressure * 50, 60);
17
+ const queuePenalty = Math.min(queueLength * 3, 25);
18
+ const failurePenalty = Math.min(failed * 5, 40);
19
+ const stabilityIndex = Math.max(
20
+ 0,
21
+ Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)
22
+ );
23
+ state2.metrics = {
24
+ ...state2.metrics,
25
+ cpuPressure,
26
+ ramPressure,
27
+ pressure,
28
+ queueLength,
29
+ completed: state2.tasks.filter((t) => t.status === "completed").length,
30
+ failed,
31
+ stabilityIndex
32
+ };
33
+ return state2;
34
+ }
35
+
36
+ // src/engine/policy.ts
37
+ var POLICIES = {
38
+ FAIRNESS: {
39
+ starvationWeight: 2,
40
+ latenessWeight: 0.8,
41
+ failureWeight: 1,
42
+ instabilityWeight: 0.5
43
+ },
44
+ BALANCED: {
45
+ starvationWeight: 0.5,
46
+ latenessWeight: 1,
47
+ failureWeight: 2,
48
+ instabilityWeight: 1
49
+ },
50
+ THROUGHPUT: {
51
+ starvationWeight: 0.1,
52
+ latenessWeight: 1.5,
53
+ failureWeight: 3,
54
+ instabilityWeight: 2
55
+ }
56
+ };
57
+
58
+ // src/engine/cost.ts
59
+ function computeTaskCost(task, state2) {
60
+ const policy = POLICIES[state2.policy];
61
+ const now = state2.time;
62
+ const pressure = state2.metrics.pressure;
63
+ const waitingTime = task.startedAt === void 0 ? now - task.createdAt : 0;
64
+ const starvation = waitingTime * policy.starvationWeight;
65
+ const latenessTime = Math.max(0, now - task.deadline);
66
+ const lateness = latenessTime * policy.latenessWeight;
67
+ const failureRisk = task.failureProbability * pressure * policy.failureWeight;
68
+ const instability = pressure * pressure * policy.instabilityWeight;
69
+ const total = starvation + lateness + failureRisk + instability;
70
+ return {
71
+ starvation,
72
+ lateness,
73
+ failureRisk,
74
+ instability,
75
+ total
76
+ };
77
+ }
78
+
79
+ // src/engine/execution.ts
80
+ function sampleUsage(curve, rng2) {
81
+ const spread = curve.peak - curve.base;
82
+ const noise = (rng2() - 0.5) * 2;
83
+ const usage = curve.base + spread * curve.variance * noise;
84
+ return Math.max(0, usage);
85
+ }
86
+ function slowdownFactor(pressure) {
87
+ return 1 + pressure * pressure;
88
+ }
89
+
90
+ // src/engine/scheduler.ts
91
+ var MAX_PRESSURE = 1.2;
92
+ function phaseFailureMultiplier(phase) {
93
+ return phase === "io" ? 1.6 : 1;
94
+ }
95
+ function schedule(state2, dt, rng2) {
96
+ const now = state2.time;
97
+ for (const t of state2.tasks) {
98
+ if (t.status === "queued" && t.maxQueueTime !== void 0 && now - t.createdAt > t.maxQueueTime && state2.metrics.pressure > 1) {
99
+ t.status = "failed";
100
+ t.failureType = "starvation";
101
+ t.failureReason = "Starvation: task waited too long in queue under pressure";
102
+ }
103
+ }
104
+ const queued = state2.tasks.filter((t) => t.status === "queued");
105
+ if (state2.metrics.pressure > MAX_PRESSURE && queued.length > 0) {
106
+ const worst = queued.map((t) => ({ t, cost: computeTaskCost(t, state2).total })).sort((a, b) => b.cost - a.cost)[0].t;
107
+ worst.status = "failed";
108
+ worst.failureType = "load_shed";
109
+ worst.failureReason = "Load shed: system pressure exceeded safe threshold";
110
+ }
111
+ const queuedWithCost = state2.tasks.filter((t) => t.status === "queued").map((t) => ({ t, cost: computeTaskCost(t, state2).total }));
112
+ let sortedQueued;
113
+ switch (state2.policy) {
114
+ case "THROUGHPUT":
115
+ sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);
116
+ break;
117
+ case "FAIRNESS":
118
+ sortedQueued = queuedWithCost.sort(
119
+ (a, b) => a.t.createdAt - b.t.createdAt
120
+ );
121
+ break;
122
+ case "BALANCED":
123
+ default:
124
+ sortedQueued = queuedWithCost.sort(
125
+ (a, b) => 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)
126
+ );
127
+ }
128
+ let runningCount = state2.tasks.filter((t) => t.status === "running").length;
129
+ for (const { t } of sortedQueued) {
130
+ if (runningCount >= state2.config.maxConcurrentTasks) break;
131
+ t.status = "running";
132
+ t.startedAt = now;
133
+ t.expectedEndAt = now + t.execution.meanDuration;
134
+ t.currentRAM = sampleUsage(t.execution.ramCurve, rng2);
135
+ runningCount++;
136
+ }
137
+ const running = state2.tasks.filter((t) => t.status === "running");
138
+ const cpuTasks = running.filter((t) => t.phase === "cpu");
139
+ const cpuPerTask = cpuTasks.length > 0 ? state2.resources.totalCPU / cpuTasks.length : 0;
140
+ let totalUsedRAM = 0;
141
+ for (const t of running) {
142
+ if (t.currentRAM !== void 0) {
143
+ totalUsedRAM += t.currentRAM;
144
+ }
145
+ }
146
+ state2.metrics.ramPressure = totalUsedRAM / state2.resources.totalRAM;
147
+ for (const t of running) {
148
+ const cpuSlow = slowdownFactor(state2.metrics.cpuPressure);
149
+ if (t.phase === "cpu") {
150
+ t.progress += cpuPerTask / state2.resources.totalCPU * (dt / t.execution.meanDuration) / cpuSlow;
151
+ } else {
152
+ const ramSlow = 1 + Math.max(0, state2.metrics.ramPressure - 1);
153
+ t.progress += 0.3 * dt / t.execution.meanDuration / ramSlow;
154
+ }
155
+ if (t.deadline !== void 0 && t.startedAt !== void 0) {
156
+ const effectiveDeadline = t.deadline * Math.max(1, state2.metrics.pressure);
157
+ if (now - t.startedAt > effectiveDeadline && state2.metrics.pressure > 1) {
158
+ t.status = "failed";
159
+ t.failureType = "timeout";
160
+ t.failureReason = "Deadline exceeded under sustained pressure";
161
+ continue;
162
+ }
163
+ }
164
+ const runTime = t.startedAt !== void 0 ? now - t.startedAt : 0;
165
+ const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);
166
+ const lambda = t.failureProbability * phaseFailureMultiplier(t.phase) * fatigueMultiplier * state2.metrics.pressure;
167
+ const perTickRisk = 1 - Math.exp(-lambda * dt);
168
+ if (rng2() < perTickRisk) {
169
+ t.status = "failed";
170
+ t.failureType = "pressure";
171
+ t.failureReason = `Execution failure (\u03BB=${lambda.toFixed(3)})`;
172
+ continue;
173
+ }
174
+ if (t.progress >= 1) {
175
+ t.status = "completed";
176
+ }
177
+ if (rng2() < 0.15) {
178
+ t.phase = t.phase === "cpu" ? "io" : "cpu";
179
+ }
180
+ }
181
+ return state2;
182
+ }
183
+
184
+ // src/engine/tick.ts
185
+ function tick(state2, dt, rng2) {
186
+ let next = { ...state2, time: state2.time + dt };
187
+ next = computeMetrics(next);
188
+ next = schedule(next, dt, rng2);
189
+ next = computeMetrics(next);
190
+ return next;
191
+ }
192
+
193
+ // src/engine/random.ts
194
+ function createRNG(seed) {
195
+ let t = seed >>> 0;
196
+ return function() {
197
+ t += 1831565813;
198
+ let r = Math.imul(t ^ t >>> 15, 1 | t);
199
+ r ^= r + Math.imul(r ^ r >>> 7, 61 | r);
200
+ return ((r ^ r >>> 14) >>> 0) / 4294967296;
201
+ };
202
+ }
203
+
204
+ // src/worker/simulator.worker.ts
205
+ console.log("\u{1F525} WORKER FILE EXECUTED");
206
+ var currentSeed = 1;
207
+ var rng = createRNG(currentSeed);
208
+ var state = null;
209
+ var interval = null;
210
+ var TICK_MS = 100;
211
+ var sustainedPressureTicks = 0;
212
+ var COLLAPSE_PRESSURE = 1.5;
213
+ var COLLAPSE_TICKS = 10;
214
+ var eventLog = [];
215
+ self.onmessage = (event) => {
216
+ const msg = event.data;
217
+ if (state && !["STATE", "INIT"].includes(msg.type)) {
218
+ eventLog.push({
219
+ time: state.time,
220
+ message: msg
221
+ });
222
+ }
223
+ switch (msg.type) {
224
+ case "INIT": {
225
+ state = structuredClone(msg.payload.state);
226
+ initialSnapshot = structuredClone(msg.payload.state);
227
+ currentSeed = msg.payload.seed ?? 1;
228
+ rng = createRNG(currentSeed);
229
+ eventLog = [];
230
+ sustainedPressureTicks = 0;
231
+ post();
232
+ break;
233
+ }
234
+ case "START": {
235
+ if (!state || interval !== null) return;
236
+ interval = setInterval(runTick, TICK_MS);
237
+ break;
238
+ }
239
+ case "PAUSE": {
240
+ if (interval !== null) {
241
+ clearInterval(interval);
242
+ interval = null;
243
+ }
244
+ break;
245
+ }
246
+ case "STEP": {
247
+ runTick();
248
+ break;
249
+ }
250
+ case "SET_CONFIG": {
251
+ if (!state) return;
252
+ state.config = {
253
+ ...state.config,
254
+ ...msg.payload
255
+ };
256
+ post();
257
+ break;
258
+ }
259
+ case "ADD_TASK": {
260
+ if (!state) return;
261
+ state.tasks.push({
262
+ ...msg.payload,
263
+ createdAt: state.time
264
+ });
265
+ break;
266
+ }
267
+ case "SET_POLICY": {
268
+ if (!state) return;
269
+ state.policy = msg.payload;
270
+ break;
271
+ }
272
+ case "SET_RESOURCES": {
273
+ if (!state) return;
274
+ state.resources = {
275
+ ...state.resources,
276
+ ...msg.payload
277
+ };
278
+ for (const w of state.workers) {
279
+ w.maxCPU = state.resources.totalCPU;
280
+ w.maxRAM = state.resources.totalRAM;
281
+ }
282
+ post();
283
+ break;
284
+ }
285
+ case "EXPORT_REPLAY": {
286
+ postMessage({
287
+ type: "REPLAY_DATA",
288
+ payload: {
289
+ seed: currentSeed,
290
+ events: eventLog
291
+ }
292
+ });
293
+ break;
294
+ }
295
+ case "REPLAY": {
296
+ if (!initialSnapshot) return;
297
+ state = structuredClone(initialSnapshot);
298
+ rng = createRNG(msg.payload.seed);
299
+ sustainedPressureTicks = 0;
300
+ for (const e of msg.payload.events) {
301
+ applyEvent(e.message);
302
+ }
303
+ post();
304
+ break;
305
+ }
306
+ }
307
+ };
308
+ function runTick() {
309
+ if (!state) return;
310
+ state = tick(state, TICK_MS / 1e3, rng);
311
+ if (state.metrics.pressure > COLLAPSE_PRESSURE) {
312
+ sustainedPressureTicks++;
313
+ } else {
314
+ sustainedPressureTicks = 0;
315
+ }
316
+ if (state.metrics.stabilityIndex <= 15 || sustainedPressureTicks >= COLLAPSE_TICKS) {
317
+ postMessage({
318
+ type: "COLLAPSE",
319
+ payload: {
320
+ time: state.time,
321
+ stabilityIndex: state.metrics.stabilityIndex,
322
+ pressure: state.metrics.pressure,
323
+ reason: sustainedPressureTicks >= COLLAPSE_TICKS ? "Sustained system pressure" : "System stability degraded beyond recovery"
324
+ }
325
+ });
326
+ clearInterval(interval);
327
+ interval = null;
328
+ return;
329
+ }
330
+ post();
331
+ }
332
+ function post() {
333
+ postMessage({
334
+ type: "STATE",
335
+ payload: state
336
+ });
337
+ }
338
+ var initialSnapshot = null;
339
+ function applyEvent(msg) {
340
+ switch (msg.type) {
341
+ case "ADD_TASK":
342
+ state?.tasks.push({
343
+ ...msg.payload,
344
+ createdAt: state.time
345
+ });
346
+ break;
347
+ case "SET_POLICY":
348
+ if (state) state.policy = msg.payload;
349
+ break;
350
+ case "SET_RESOURCES":
351
+ if (state) {
352
+ state.resources = {
353
+ ...state.resources,
354
+ ...msg.payload
355
+ };
356
+ }
357
+ break;
358
+ case "START":
359
+ if (!interval) {
360
+ interval = setInterval(runTick, TICK_MS);
361
+ }
362
+ break;
363
+ case "PAUSE":
364
+ if (interval) {
365
+ clearInterval(interval);
366
+ interval = null;
367
+ }
368
+ break;
369
+ }
370
+ }
371
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/metrics.ts","../src/engine/policy.ts","../src/engine/cost.ts","../src/engine/execution.ts","../src/engine/scheduler.ts","../src/engine/tick.ts","../src/engine/random.ts","../src/worker/simulator.worker.ts"],"sourcesContent":["import { SystemState } from \"../core/state\";\r\n\r\nexport function computeMetrics(state: SystemState): SystemState {\r\n let usedCPU = 0;\r\n let usedRAM = 0;\r\n\r\n for (const task of state.tasks) {\r\n if (task.status === \"running\") {\r\n usedCPU += task.execution.cpuCurve.base;\r\n usedRAM += task.execution.ramCurve.base;\r\n }\r\n }\r\n\r\n const cpuPressure = usedCPU / state.resources.totalCPU;\r\n const ramPressure = usedRAM / state.resources.totalRAM;\r\n const pressure = Math.max(cpuPressure, ramPressure);\r\n\r\n const queueLength = state.tasks.filter((t) => t.status === \"queued\").length;\r\n\r\n const failed = state.tasks.filter((t) => t.status === \"failed\").length;\r\n\r\n // 🔥 System Stability Index (0–100)\r\n const pressurePenalty = Math.min(pressure * 50, 60);\r\n const queuePenalty = Math.min(queueLength * 3, 25);\r\n const failurePenalty = Math.min(failed * 5, 40);\r\n\r\n const stabilityIndex = Math.max(\r\n 0,\r\n Math.round(100 - pressurePenalty - queuePenalty - failurePenalty)\r\n );\r\n\r\n state.metrics = {\r\n ...state.metrics,\r\n cpuPressure,\r\n ramPressure,\r\n pressure,\r\n queueLength,\r\n completed: state.tasks.filter((t) => t.status === \"completed\").length,\r\n failed,\r\n stabilityIndex,\r\n };\r\n\r\n return state;\r\n}\r\n","export type PolicyName = \"FAIRNESS\" | \"BALANCED\" | \"THROUGHPUT\";\r\n\r\nexport type Policy = {\r\n starvationWeight: number;\r\n latenessWeight: number;\r\n failureWeight: number;\r\n instabilityWeight: number;\r\n};\r\n\r\nexport const POLICIES: Record<PolicyName, Policy> = {\r\n FAIRNESS: {\r\n starvationWeight: 2,\r\n latenessWeight: 0.8,\r\n failureWeight: 1,\r\n instabilityWeight: 0.5,\r\n },\r\n BALANCED: {\r\n starvationWeight: 0.5,\r\n latenessWeight: 1,\r\n failureWeight: 2,\r\n instabilityWeight: 1,\r\n },\r\n THROUGHPUT: {\r\n starvationWeight: 0.1,\r\n latenessWeight: 1.5,\r\n failureWeight: 3,\r\n instabilityWeight: 2,\r\n },\r\n};\r\n","import { Task } from \"../core/task\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { POLICIES } from \"./policy\";\r\n\r\nexport type CostBreakdown = {\r\n starvation: number;\r\n lateness: number;\r\n failureRisk: number;\r\n instability: number;\r\n total: number;\r\n};\r\n\r\nexport function computeTaskCost(task: Task, state: SystemState): CostBreakdown {\r\n const policy = POLICIES[state.policy];\r\n const now = state.time;\r\n const pressure = state.metrics.pressure;\r\n\r\n // --- Starvation ---\r\n const waitingTime = task.startedAt === undefined ? now - task.createdAt : 0;\r\n\r\n const starvation = waitingTime * policy.starvationWeight;\r\n\r\n // --- Lateness ---\r\n const latenessTime = Math.max(0, now - task.deadline);\r\n\r\n const lateness = latenessTime * policy.latenessWeight;\r\n\r\n // --- Failure Risk (expected loss) ---\r\n const failureRisk = task.failureProbability * pressure * policy.failureWeight;\r\n\r\n // --- System Instability ---\r\n const instability = pressure * pressure * policy.instabilityWeight;\r\n\r\n const total = starvation + lateness + failureRisk + instability;\r\n\r\n return {\r\n starvation,\r\n lateness,\r\n failureRisk,\r\n instability,\r\n total,\r\n };\r\n}\r\n","import { ResourceCurve } from \"../core/task\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function sampleUsage(curve: ResourceCurve, rng: RNG): number {\r\n const spread = curve.peak - curve.base;\r\n\r\n // centered noise in [-0.5, 0.5]\r\n const noise = (rng() - 0.5) * 2;\r\n\r\n const usage = curve.base + spread * curve.variance * noise;\r\n\r\n return Math.max(0, usage);\r\n}\r\n\r\nexport function slowdownFactor(pressure: number): number {\r\n return 1 + pressure * pressure;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeTaskCost } from \"./cost\";\r\nimport { slowdownFactor } from \"./execution\";\r\nimport { RNG } from \"./random\";\r\nimport { sampleUsage } from \"./execution\";\r\n\r\nconst MAX_PRESSURE = 1.2;\r\n\r\nfunction phaseFailureMultiplier(phase: \"cpu\" | \"io\") {\r\n return phase === \"io\" ? 1.6 : 1.0;\r\n}\r\n\r\nexport function schedule(\r\n state: SystemState,\r\n dt: number,\r\n rng: RNG\r\n): SystemState {\r\n const now = state.time;\r\n\r\n /* =========================================================\r\n 1. STARVATION FAILURE (queued too long, under pressure)\r\n ========================================================= */\r\n\r\n for (const t of state.tasks) {\r\n if (\r\n t.status === \"queued\" &&\r\n t.maxQueueTime !== undefined &&\r\n now - t.createdAt > t.maxQueueTime &&\r\n state.metrics.pressure > 1\r\n ) {\r\n t.status = \"failed\";\r\n t.failureType = \"starvation\";\r\n t.failureReason =\r\n \"Starvation: task waited too long in queue under pressure\";\r\n }\r\n }\r\n\r\n const queued = state.tasks.filter((t) => t.status === \"queued\");\r\n\r\n /* =========================================================\r\n 2. LOAD SHEDDING (system protection)\r\n ========================================================= */\r\n\r\n if (state.metrics.pressure > MAX_PRESSURE && queued.length > 0) {\r\n const worst = queued\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }))\r\n .sort((a, b) => b.cost - a.cost)[0].t;\r\n\r\n worst.status = \"failed\";\r\n worst.failureType = \"load_shed\";\r\n worst.failureReason = \"Load shed: system pressure exceeded safe threshold\";\r\n }\r\n\r\n /* =========================================================\r\n 3. ADMISSION CONTROL (concurrency-limited)\r\n ========================================================= */\r\n\r\n const queuedWithCost = state.tasks\r\n .filter((t) => t.status === \"queued\")\r\n .map((t) => ({ t, cost: computeTaskCost(t, state).total }));\r\n\r\n let sortedQueued;\r\n\r\n switch (state.policy) {\r\n case \"THROUGHPUT\":\r\n // favor cheap tasks → maximize completions\r\n sortedQueued = queuedWithCost.sort((a, b) => a.cost - b.cost);\r\n break;\r\n\r\n case \"FAIRNESS\":\r\n // favor oldest tasks\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) => a.t.createdAt - b.t.createdAt\r\n );\r\n break;\r\n\r\n case \"BALANCED\":\r\n default:\r\n // mix age + cost\r\n sortedQueued = queuedWithCost.sort(\r\n (a, b) =>\r\n 0.5 * (a.cost - b.cost) + 0.5 * (a.t.createdAt - b.t.createdAt)\r\n );\r\n }\r\n\r\n let runningCount = state.tasks.filter((t) => t.status === \"running\").length;\r\n\r\n for (const { t } of sortedQueued) {\r\n if (runningCount >= state.config.maxConcurrentTasks) break;\r\n\r\n t.status = \"running\";\r\n t.startedAt = now;\r\n t.expectedEndAt = now + t.execution.meanDuration;\r\n\r\n t.currentRAM = sampleUsage(t.execution.ramCurve, rng);\r\n\r\n runningCount++;\r\n }\r\n\r\n /* =========================================================\r\n 4. EXECUTE RUNNING TASKS\r\n ========================================================= */\r\n\r\n const running = state.tasks.filter((t) => t.status === \"running\");\r\n\r\n /* ---------- CPU SHARING ---------- */\r\n const cpuTasks = running.filter((t) => t.phase === \"cpu\");\r\n const cpuPerTask =\r\n cpuTasks.length > 0 ? state.resources.totalCPU / cpuTasks.length : 0;\r\n\r\n /* ---------- RAM ACCUMULATION ---------- */\r\n let totalUsedRAM = 0;\r\n for (const t of running) {\r\n if (t.currentRAM !== undefined) {\r\n totalUsedRAM += t.currentRAM;\r\n }\r\n }\r\n\r\n state.metrics.ramPressure = totalUsedRAM / state.resources.totalRAM;\r\n\r\n /* ---------- EXECUTION LOOP ---------- */\r\n for (const t of running) {\r\n const cpuSlow = slowdownFactor(state.metrics.cpuPressure);\r\n\r\n if (t.phase === \"cpu\") {\r\n t.progress +=\r\n ((cpuPerTask / state.resources.totalCPU) *\r\n (dt / t.execution.meanDuration)) /\r\n cpuSlow;\r\n } else {\r\n const ramSlow = 1 + Math.max(0, state.metrics.ramPressure - 1);\r\n\r\n t.progress += (0.3 * dt) / t.execution.meanDuration / ramSlow;\r\n }\r\n\r\n /* ---------- TIMEOUT FAILURE ---------- */\r\n if (t.deadline !== undefined && t.startedAt !== undefined) {\r\n const effectiveDeadline =\r\n t.deadline * Math.max(1, state.metrics.pressure);\r\n\r\n if (now - t.startedAt > effectiveDeadline && state.metrics.pressure > 1) {\r\n t.status = \"failed\";\r\n t.failureType = \"timeout\";\r\n t.failureReason = \"Deadline exceeded under sustained pressure\";\r\n continue;\r\n }\r\n }\r\n\r\n /* ---------- PRESSURE-CORRELATED FAILURE ---------- */\r\n const runTime = t.startedAt !== undefined ? now - t.startedAt : 0;\r\n\r\n const fatigueMultiplier = 1 + Math.min(runTime / 10, 1);\r\n\r\n const lambda =\r\n t.failureProbability *\r\n phaseFailureMultiplier(t.phase) *\r\n fatigueMultiplier *\r\n state.metrics.pressure;\r\n\r\n const perTickRisk = 1 - Math.exp(-lambda * dt);\r\n\r\n if (rng() < perTickRisk) {\r\n t.status = \"failed\";\r\n t.failureType = \"pressure\";\r\n t.failureReason = `Execution failure (λ=${lambda.toFixed(3)})`;\r\n continue;\r\n }\r\n\r\n /* ---------- COMPLETION ---------- */\r\n if (t.progress >= 1) {\r\n t.status = \"completed\";\r\n }\r\n\r\n /* ---------- ASYNC ILLUSION ---------- */\r\n if (rng() < 0.15) {\r\n t.phase = t.phase === \"cpu\" ? \"io\" : \"cpu\";\r\n }\r\n }\r\n\r\n return state;\r\n}\r\n","import { SystemState } from \"../core/state\";\r\nimport { computeMetrics } from \"./metrics\";\r\nimport { schedule } from \"./scheduler\";\r\nimport { RNG } from \"./random\";\r\n\r\nexport function tick(state: SystemState, dt: number, rng: RNG): SystemState {\r\n let next = { ...state, time: state.time + dt };\r\n\r\n next = computeMetrics(next);\r\n next = schedule(next, dt, rng);\r\n next = computeMetrics(next);\r\n\r\n return next;\r\n}\r\n","export type RNG = () => number;\r\n\r\nexport function createRNG(seed: number): RNG {\r\n let t = seed >>> 0;\r\n\r\n return function () {\r\n t += 0x6d2b79f5;\r\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\r\n r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);\r\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n","/// <reference lib=\"webworker\" />\r\nconsole.log(\"🔥 WORKER FILE EXECUTED\");\r\nimport { tick } from \"../engine/tick\";\r\nimport { SystemState } from \"../core/state\";\r\nimport { Task } from \"../core/task\";\r\nimport { PolicyName } from \"../engine/policy\";\r\nimport { SystemResources } from \"../core/resources\";\r\nimport { createRNG } from \"../engine/random\";\r\nlet currentSeed: number = 1;\r\nlet rng = createRNG(currentSeed);\r\n\r\nlet state: SystemState | null = null;\r\nlet interval: ReturnType<typeof setInterval> | null = null;\r\n\r\nconst TICK_MS = 100;\r\nlet sustainedPressureTicks = 0;\r\nconst COLLAPSE_PRESSURE = 1.5;\r\nconst COLLAPSE_TICKS = 10;\r\n\r\nlet eventLog: Array<{\r\n time: number;\r\n message: any;\r\n}> = [];\r\n\r\nself.onmessage = (event: MessageEvent) => {\r\n const msg = event.data;\r\n // Log user actions (but NOT INIT or STATE)\r\n if (state && ![\"STATE\", \"INIT\"].includes(msg.type)) {\r\n eventLog.push({\r\n time: state.time,\r\n message: msg,\r\n });\r\n }\r\n switch (msg.type) {\r\n case \"INIT\": {\r\n state = structuredClone(msg.payload.state);\r\n initialSnapshot = structuredClone(msg.payload.state);\r\n currentSeed = msg.payload.seed ?? 1;\r\n rng = createRNG(currentSeed);\r\n eventLog = [];\r\n sustainedPressureTicks = 0;\r\n post();\r\n break;\r\n }\r\n\r\n case \"START\": {\r\n if (!state || interval !== null) return;\r\n interval = setInterval(runTick, TICK_MS);\r\n break;\r\n }\r\n\r\n case \"PAUSE\": {\r\n if (interval !== null) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n\r\n case \"STEP\": {\r\n runTick();\r\n break;\r\n }\r\n case \"SET_CONFIG\": {\r\n if (!state) return;\r\n\r\n state.config = {\r\n ...state.config,\r\n ...msg.payload,\r\n };\r\n\r\n post();\r\n break;\r\n }\r\n case \"ADD_TASK\": {\r\n if (!state) return;\r\n\r\n state.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n\r\n break;\r\n }\r\n\r\n case \"SET_POLICY\": {\r\n if (!state) return;\r\n state.policy = msg.payload as PolicyName;\r\n break;\r\n }\r\n\r\n case \"SET_RESOURCES\": {\r\n if (!state) return;\r\n state.resources = {\r\n ...state.resources,\r\n ...(msg.payload as Partial<SystemResources>),\r\n };\r\n for (const w of state.workers) {\r\n w.maxCPU = state.resources.totalCPU;\r\n w.maxRAM = state.resources.totalRAM;\r\n }\r\n post();\r\n break;\r\n }\r\n case \"EXPORT_REPLAY\": {\r\n postMessage({\r\n type: \"REPLAY_DATA\",\r\n payload: {\r\n seed: currentSeed,\r\n events: eventLog,\r\n },\r\n });\r\n break;\r\n }\r\n\r\n case \"REPLAY\": {\r\n if (!initialSnapshot) return;\r\n\r\n // Reset system\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(msg.payload.seed);\r\n sustainedPressureTicks = 0;\r\n\r\n // Re-apply events deterministically\r\n for (const e of msg.payload.events) {\r\n applyEvent(e.message);\r\n }\r\n\r\n post();\r\n break;\r\n }\r\n }\r\n};\r\n\r\nfunction runTick() {\r\n if (!state) return;\r\n\r\n state = tick(state, TICK_MS / 1000, rng);\r\n\r\n if (state.metrics.pressure > COLLAPSE_PRESSURE) {\r\n sustainedPressureTicks++;\r\n } else {\r\n sustainedPressureTicks = 0;\r\n }\r\n\r\n if (\r\n state.metrics.stabilityIndex <= 15 ||\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ) {\r\n postMessage({\r\n type: \"COLLAPSE\",\r\n payload: {\r\n time: state.time,\r\n stabilityIndex: state.metrics.stabilityIndex,\r\n pressure: state.metrics.pressure,\r\n reason:\r\n sustainedPressureTicks >= COLLAPSE_TICKS\r\n ? \"Sustained system pressure\"\r\n : \"System stability degraded beyond recovery\",\r\n },\r\n });\r\n\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n post();\r\n}\r\n\r\nfunction post() {\r\n postMessage({\r\n type: \"STATE\",\r\n payload: state,\r\n });\r\n}\r\n\r\nlet initialSnapshot: SystemState | null = null;\r\n\r\nfunction reset() {\r\n if (!initialSnapshot) return;\r\n\r\n state = structuredClone(initialSnapshot);\r\n rng = createRNG(currentSeed);\r\n}\r\n\r\nfunction applyEvent(msg: any) {\r\n switch (msg.type) {\r\n case \"ADD_TASK\":\r\n state?.tasks.push({\r\n ...msg.payload,\r\n createdAt: state.time,\r\n });\r\n break;\r\n\r\n case \"SET_POLICY\":\r\n if (state) state.policy = msg.payload;\r\n break;\r\n\r\n case \"SET_RESOURCES\":\r\n if (state) {\r\n state.resources = {\r\n ...state.resources,\r\n ...msg.payload,\r\n };\r\n }\r\n break;\r\n\r\n case \"START\":\r\n if (!interval) {\r\n interval = setInterval(runTick, TICK_MS);\r\n }\r\n break;\r\n\r\n case \"PAUSE\":\r\n if (interval) {\r\n clearInterval(interval);\r\n interval = null;\r\n }\r\n break;\r\n }\r\n}\r\n"],"mappings":"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","names":["state","state","rng","state","rng","state","rng"]}
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "synai-simulator",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": ["dist"],
8
+ "scripts": {
9
+ "build": "tsup",
10
+ "dev": "tsup --watch"
11
+ },
12
+ "devDependencies": {
13
+ "tsup": "^8.0.0",
14
+ "typescript": "^5.0.0"
15
+ }
16
+ }