128 lines · 4.7 KB · TypeScript
RawDownload
// The supervised daemon's durability as a WATCHABLE terminal recording: register// a REAL integration, REBOOT the daemon's machine for real (the on-screen// spinner runs for the actual reboot), then show the integration still there.// Same assertions as restart-persistence — but filmed, so you can press play// instead of trusting a green check. Runs against the cli-* VM targets.import { randomBytes } from "node:crypto";import { join } from "node:path"; import { expect } from "@effect/vitest";import { Effect } from "effect"; import { composePluginApi } from "@executor-js/api/server";import { openApiHttpPlugin } from "@executor-js/plugin-openapi/api"; import { withChatTheater } from "../src/clients/chat-theater";import { scenario } from "../src/scenario";import { Api, Cli, Restart, RunDir, Target } from "../src/services"; const api = composePluginApi([openApiHttpPlugin()] as const); /** Inline OpenAPI 3 spec with a single GET /ping (its server is never called). */const pingSpec = JSON.stringify({  openapi: "3.0.3",  info: { title: "Reboot Lifecycle API", version: "1.0.0" },  servers: [{ url: "http://127.0.0.1:59998" }],  paths: {    "/ping": {      get: {        operationId: "getPing",        summary: "Liveness ping",        responses: { "200": { description: "pong" } },      },    },  },}); scenario(  "Supervised daemon · an integration survives a real machine reboot (recorded)",  {},  Effect.gen(function* () {    const target = yield* Target;    const restart = yield* Restart;    const { client } = yield* Api;    const cli = yield* Cli;    const runDir = yield* RunDir;     const slug = `reboot-film-${randomBytes(4).toString("hex")}`;     yield* withChatTheater(      cli,      { title: "executor — supervised daemon", record: join(runDir, "terminal.cast") },      (chat) =>        Effect.gen(function* () {          yield* chat.user("If this machine reboots, do my connected integrations survive?");          yield* chat.assistant(            "Let's prove it — register a real integration, reboot the daemon's machine for real, then check it's still there.",          );           const before = yield* client(api, yield* target.newIdentity());           const added = yield* chat.tool(            {              name: "executor call executor.openapi.addSpec",              input: `slug: ${slug}\nspec: inline OpenAPI (GET /ping)`,              result: (a) => `registered — ${a.toolCount} tool(s)`,            },            before.openapi.addSpec({              payload: {                spec: { kind: "blob", value: pingSpec },                slug,                authenticationTemplate: [],              },            }),          );          expect(added.toolCount, "the spec registered with tools").toBeGreaterThan(0);           const listed = yield* chat.tool(            {              name: "executor tools integrations",              result: (rows) =>                rows.map((r) => String(r.slug)).includes(slug) ? `${slug} is listed` : "NOT listed",            },            before.integrations.list(),          );          expect(            listed.map((i) => String(i.slug)),            "listed before the reboot",          ).toContain(slug);           // The spinner here runs for the ENTIRE real reboot — the supervised          // service must auto-start at boot for this to ever return.          yield* chat.tool(            {              name: "reboot the daemon's machine",              input: "guest OS reboot — the OS service manager must auto-start the daemon at boot",              result: () => "back online; daemon auto-started",            },            restart(),          );           const after = yield* client(api, yield* target.newIdentity());          yield* Effect.ensuring(            Effect.gen(function* () {              const survived = yield* chat.tool(                {                  name: "executor tools integrations",                  result: (rows) =>                    rows.map((r) => String(r.slug)).includes(slug)                      ? `${slug} SURVIVED the reboot`                      : "VANISHED",                },                after.integrations.list(),              );              expect(                survived.map((i) => String(i.slug)),                "survived the reboot",              ).toContain(slug);              yield* chat.assistant(                "It survived — the OS restarted the daemon at boot and its data was intact.",              );            }),            // Shared guest, but ephemeral; still, never leave the spec behind.            after.openapi.removeSpec({ params: { slug } }).pipe(Effect.ignore),          );        }),    );  }),);