SPB Git

Repository Public

chaos-logic.ts 2.9 KB 63 lines typescript

1/** Run logic of the chaos suite: 6 steps mixing every effect class. Effects are files under ctx.workspaceAbs. */2import fs from 'node:fs';3import path from 'node:path';4import type { RunLogic } from '../../src/index.js';56export const STEP_NAMES = ['s0', 's1', 's2', 's3', 's4', 's5'];78export function makeChaosLogic(opts: { assumed: boolean }): RunLogic {9  return async (ctx) => {10    const dir = ctx.workspaceAbs;11    const count = (i: number): void => fs.appendFileSync(path.join(dir, 'exec.log'), `s${i}\n`);1213    const a = await ctx.step({ kind: 'calc', name: 's0', effect: 'pure', request: { x: 20 } }, async () => {14      count(0);15      return { result: { v: 42 } };16    });17    await ctx.emit('system.notice', { mark: 'after-s0' });18    const b = await ctx.step({ kind: 'tool_call', name: 's1', effect: 'read', request: { file: 'input.txt' } }, async () => {19      count(1);20      return { result: { content: fs.readFileSync(path.join(dir, 'input.txt'), 'utf8') } };21    });22    const c = await ctx.step({ kind: 'tool_call', name: 's2', effect: 'idempotent_write', request: { content: 'hello' } }, async (idem) => {23      count(2);24      fs.mkdirSync(path.join(dir, 'idem'), { recursive: true });25      fs.writeFileSync(path.join(dir, 'idem', idem), 'hello'); // keyed by idem_key: a re-execution overwrites26      return { result: { written: true } };27    });28    const ledger = path.join(dir, 'ledger.txt');29    const d = await ctx.step(30      {31        kind: 'tool_call', name: 's3', effect: 'non_idempotent', request: { to: 'ledger' },32        reconcile: async (_req, idem) => {33          const lines = fs.existsSync(ledger) ? fs.readFileSync(ledger, 'utf8').split('\n') : [];34          return lines.includes(idem) ? { done: true, result: { ledgered: true } } : { done: false };35        },36      },37      async (idem) => {38        count(3);39        fs.appendFileSync(ledger, `${idem}\n`);40        return { result: { ledgered: true } };41      },42    );43    await ctx.emit('system.notice', { mark: 'after-s3' });44    const e = await ctx.step(45      {46        kind: 'tool_call', name: 's4', effect: 'non_idempotent', request: { send: 'mail' },47        ...(opts.assumed ? { assumedResult: () => ({ sent: true }) as Record<string, unknown> } : {}),48      },49      async (idem): Promise<{ result: Record<string, unknown> }> => {50        count(4);51        fs.appendFileSync(path.join(dir, 'unprobed.txt'), `${idem}\n`);52        return { result: { sent: true } };53      },54    );55    const f = await ctx.step({ kind: 'model_call', name: 's5', effect: 'model_call', request: { prompt: [a, b, c, d, e] } }, async () => {56      count(5);57      return { result: { text: 'ok' }, usage: { usd: 0.01, inputTokens: 10, outputTokens: 5 } };58    });59    await ctx.emit('system.notice', { mark: 'end' });60    return { status: 'done', summary: 'chaos run complete', payload: { a, b, c, d, e, f }, artifacts: [], evidence: [], openQuestions: [] };61  };62}63
Files main
Menu

Theme