Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:54:48.752Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

fake_effectd.mjs

936 lines · 29.4 KB · javascript
1#!/usr/bin/env node
2/**
3 * Minimal omega-effectd framed-protocol fixture for Rust supervisor tests.
4 * Speaks openagents.omega.effectd.v1 on stdin/stdout.
5 */
6import { createInterface } from "node:readline"
7import { mkdirSync, readFileSync, writeFileSync, existsSync } from "node:fs"
8import path from "node:path"
9
10const schema = "openagents.omega.effectd.v1"
11const oversizedHealthResponse = process.argv.includes("--oversized-health-response")
12const hostRequestHealth = process.argv.includes("--host-request-health")
13const unavailableHostRequestHealth = process.argv.includes("--unavailable-host-request-health")
14const staleHostRequestHealth = process.argv.includes("--stale-host-request-health")
15const staleHealthResponse = process.argv.includes("--stale-health-response")
16const dataRoot = process.env.OPENAGENTS_OMEGA_EFFECTD_DATA_ROOT
17if (!dataRoot) {
18  console.error("OPENAGENTS_OMEGA_EFFECTD_DATA_ROOT is required")
19  process.exit(2)
20}
21
22const runsFile = path.join(dataRoot, "full-auto", "runs.json")
23const bindingsFile = path.join(dataRoot, "full-auto", "native-bindings.json")
24const agentComputerSessionsFile = path.join(dataRoot, "agent-computer", "sessions.json")
25mkdirSync(path.join(dataRoot, "full-auto"), { recursive: true, mode: 0o700 })
26mkdirSync(path.join(dataRoot, "agent-computer"), { recursive: true, mode: 0o700 })
27
28let generation = 0
29let running = false
30let pendingHostHealth = null
31
32const respond = (id, gen, ok, result, error) => {
33  process.stdout.write(
34    `${JSON.stringify({
35      schema,
36      kind: "response",
37      id,
38      generation: gen,
39      ok,
40      ...(result === undefined ? {} : { result }),
41      ...(error === undefined ? {} : { error }),
42    })}\n`,
43  )
44}
45
46const loadRuns = () => {
47  if (!existsSync(runsFile)) return []
48  try {
49    const parsed = JSON.parse(readFileSync(runsFile, "utf8"))
50    return Array.isArray(parsed.runs) ? parsed.runs : []
51  } catch {
52    return []
53  }
54}
55
56const saveRuns = (runs) => {
57  writeFileSync(
58    runsFile,
59    JSON.stringify(
60      { schema: "openagents.desktop.full_auto_run_registry.v1", runs },
61      null,
62      2,
63    ),
64  )
65}
66
67const loadBindings = () => {
68  if (!existsSync(bindingsFile)) return []
69  try {
70    const parsed = JSON.parse(readFileSync(bindingsFile, "utf8"))
71    return Array.isArray(parsed.bindings) ? parsed.bindings : []
72  } catch {
73    return []
74  }
75}
76
77const saveBindings = (bindings) => {
78  writeFileSync(
79    bindingsFile,
80    JSON.stringify(
81      {
82        schema: "openagents.omega.full_auto_native_binding.v1",
83        bindings,
84      },
85      null,
86      2,
87    ),
88  )
89}
90
91const loadAgentComputerSessions = () => {
92  if (!existsSync(agentComputerSessionsFile)) return []
93  try {
94    const parsed = JSON.parse(readFileSync(agentComputerSessionsFile, "utf8"))
95    return Array.isArray(parsed.sessions) ? parsed.sessions : []
96  } catch {
97    return []
98  }
99}
100
101const saveAgentComputerSessions = (sessions) => {
102  writeFileSync(
103    agentComputerSessionsFile,
104    JSON.stringify(
105      {
106        schema: "openagents.omega.agent_computer_session.v1",
107        sessions,
108      },
109      null,
110      2,
111    ),
112  )
113}
114
115// SARAH-NR-06 mock conversation store (in-memory; no Khala Sync).
116const SARAH_CONVERSATION_DIGEST = "aaaaaaaaaaaaaaaaaaaaaaaa"
117const SARAH_CONVERSATION_REF = `sarah.${SARAH_CONVERSATION_DIGEST}`
118const SARAH_LEGACY_THREAD_REF = `thread.sarah.${SARAH_CONVERSATION_DIGEST}`
119const sarahStore = {
120  messages: [],
121  messageSeq: 0,
122  runState: "idle",
123  activeTurnRef: null,
124}
125
126const sarahRoomState = () => ({
127  method: "sarah_room_state",
128  connection: "connected",
129  freshness: "fresh",
130  gapState: "none",
131  connectedRelays: ["mock://local"],
132  lastAcknowledgedEventId: sarahStore.messages.at(-1)?.eventId ?? null,
133  lastAcknowledgedCursor:
134    sarahStore.messages.length > 0
135      ? `cursor.${sarahStore.messages.length - 1}`
136      : null,
137  authenticated: true,
138  transport: "mock_relay",
139})
140
141const sarahSessionStatus = () => ({
142  signedIn: true,
143  accountLabel: "owner@example.com",
144  bindingState: "bound",
145  ownerPublicKeyHex: "b".repeat(64),
146  bindingExpiresAt: null,
147  transport: "mock_relay",
148})
149
150const sarahBootstrap = () => ({
151  principalRef: "principal.sarah",
152  displayName: "Sarah",
153  role: "owner_orchestrator",
154  conversationRef: SARAH_CONVERSATION_REF,
155  legacyThreadRef: SARAH_LEGACY_THREAD_REF,
156  ownerPublicKeyHex: "b".repeat(64),
157  sarahPublicKeyHex: "c".repeat(64),
158  authorityProfileRef: "docs/authority/SARAH_AUTHORITY.md",
159  authorityProfileRevision: 7,
160  roomState: sarahRoomState(),
161})
162
163const sarahSendMessage = (text) => {
164  sarahStore.messageSeq += 1
165  const turnRef = `turn.${sarahStore.messageSeq}`
166  const messageRef = `msg.${sarahStore.messageSeq}`
167  const eventId = `evt.msg.${sarahStore.messageSeq}`
168  const cursor = `cursor.${sarahStore.messages.length}`
169  sarahStore.activeTurnRef = turnRef
170  sarahStore.runState = "running"
171  sarahStore.messages.push({
172    eventId,
173    cursor,
174    role: "owner",
175    kind: "text",
176    text: String(text).slice(0, 512),
177    createdAt: new Date().toISOString(),
178    status: "accepted",
179    turnRef,
180  })
181  return {
182    accepted: true,
183    messageRef,
184    turnRef,
185    eventId,
186    cursor,
187    status: "accepted",
188  }
189}
190
191const sarahRoomSnapshot = (params) => {
192  const limit = Math.min(Math.max(Number(params.limit) || 32, 1), 64)
193  const entries = sarahStore.messages.slice(-limit).map((row) => ({
194    eventId: row.eventId,
195    cursor: row.cursor,
196    role: row.role,
197    kind: row.kind,
198    text: row.text,
199    createdAt: row.createdAt,
200    status: row.status,
201  }))
202  const cursor =
203    entries.at(-1)?.cursor ?? params.cursor ?? "cursor.start"
204  return {
205    conversationRef: SARAH_CONVERSATION_REF,
206    transcript: {
207      entries,
208      cursor,
209      nextCursor: null,
210      gapState: "none",
211    },
212    activity: {
213      entries: [],
214      cursor,
215      nextCursor: null,
216      gapState: "none",
217    },
218    runState: {
219      state: sarahStore.runState,
220      turnRef: sarahStore.activeTurnRef,
221      reason: null,
222    },
223    roomState: sarahRoomState(),
224  }
225}
226
227const sarahInterruptTurn = (turnRef) => {
228  sarahStore.runState = "interrupt_pending"
229  return {
230    accepted: true,
231    turnRef,
232    intentRef: `intent.interrupt.${sarahStore.messageSeq + 1}`,
233    status: "pending",
234    pending: true,
235  }
236}
237
238const projectAgentComputerSession = (params, state = "queued") => {
239  const startedAt = new Date().toISOString()
240  return {
241    sessionRef: `ccs.fixture.${Date.now().toString(36)}`,
242    environment: "openagents_cloud",
243    controlPlaneBaseUrl: params.controlPlaneBaseUrl,
244    repoRef: params.repoRef,
245    objectiveDigest: "fixture-objective-digest",
246    state,
247    adapter: params.adapter ?? "codex",
248    lane: params.lane ?? "cloud-gcp",
249    placementRef: "placement.fixture.ac01",
250    artifactRef: state === "completed" ? "artifact.fixture.ac01" : null,
251    agentComputerRef: "agentcomputer.fixture.ac01",
252    agentComputerState: state === "completed" ? "reclaimed" : "active",
253    startedAt,
254    updatedAt: startedAt,
255  }
256}
257
258const listRuns = () =>
259  loadRuns().map((run) => ({
260    runRef: run.runRef,
261    threadRef: run.threadRef ?? null,
262    state: run.state,
263    title: run.title,
264    updatedAt: run.updatedAt,
265  }))
266
267const healthResult = () => ({
268  ok: true,
269  status: running ? "running" : "stopped",
270  generation,
271  dataRoot,
272  activeRunCount: listRuns().filter((run) =>
273    ["running", "pausing", "paused", "retrying", "stalled"].includes(run.state),
274  ).length,
275})
276
277const detail = (run) => {
278  const binding = loadBindings().find((row) => row.runRef === run.runRef) ?? null
279  return {
280    runRef: run.runRef,
281    threadRef: run.threadRef ?? null,
282    state: run.state,
283    title: run.title,
284    objective: run.objective ?? "",
285    doneCondition: run.doneCondition ?? "",
286    workspaceRef: run.workspaceRef ?? null,
287    lane: run.lane ?? "codex-local",
288    turnCap: run.turnCap ?? 40,
289    successfulAttempts: run.successfulAttempts ?? 0,
290    failedAttempts: run.failedAttempts ?? 0,
291    stallCause: run.stallCause ?? null,
292    recoveryAction: run.recoveryAction ?? "none",
293    terminalReason: run.terminalReason ?? null,
294    startedAt: run.startedAt ?? run.createdAt ?? null,
295    updatedAt: run.updatedAt,
296    turns: run.turns ?? [],
297    nativeEvidence: binding
298      ? {
299          projectRef: binding.projectRef,
300          worktreeRef: binding.worktreeRef,
301          worktreePathDigest: binding.worktreePathDigest ?? null,
302          gitHead: binding.gitHead ?? null,
303        }
304      : null,
305  }
306}
307
308console.error(
309  JSON.stringify({
310    service: "fake-omega-effectd",
311    status: "listening",
312    protocol: schema,
313    dataRoot,
314  }),
315)
316
317const rl = createInterface({ input: process.stdin, crlfDelay: Infinity })
318for await (const line of rl) {
319  const trimmed = line.trim()
320  if (!trimmed) continue
321  let request
322  try {
323    request = JSON.parse(trimmed)
324  } catch {
325    respond("invalid", generation, false, undefined, {
326      code: "invalid_request",
327      message: "Frame was not valid JSON.",
328    })
329    continue
330  }
331  if (request.kind === "host_response" && pendingHostHealth !== null) {
332    const pending = pendingHostHealth
333    pendingHostHealth = null
334    const expectedError = pending.mode === "stale" ? "stale_generation" : "unavailable"
335    const accepted =
336      request.id === pending.hostId &&
337      request.generation === pending.hostGeneration &&
338      (pending.mode === "success"
339        ? request.ok === true && request.result?.workspaceRef === "workspace.omega.supervised"
340        : request.ok === false && request.error?.code === expectedError)
341    if (!accepted) {
342      respond(pending.request.id, generation, false, undefined, {
343        code: "invalid_request",
344        message: "Host response did not match the fixture contract.",
345      })
346      continue
347    }
348    respond(pending.request.id, generation, true, healthResult())
349    continue
350  }
351  if (request.method === "initialize") {
352    generation = request.params?.generation ?? 1
353    running = true
354    respond(request.id, generation, true, {
355      schema,
356      protocolVersion: 1,
357      serviceVersion: "0.1.0",
358      generation,
359      capabilities: [
360        "health",
361        "list_runs",
362        "get_run",
363        "start",
364        "pause",
365        "resume",
366        "handoff",
367        "stop",
368        "retry",
369        "get_capacity",
370        "decide_attention",
371        "get_report",
372        "get_receipt",
373        "apply_control_intent",
374        "get_sync_status",
375        "publish_projection",
376        "get_native_binding",
377        "assess_native_boundary",
378        "start_agent_computer_session",
379        "refresh_agent_computer_session",
380        "run_agent_computer_turn",
381        "get_agent_computer_session",
382        "list_agent_computer_sessions",
383        "sarah_session_status",
384        "sarah_bootstrap",
385        "sarah_room_snapshot",
386        "sarah_send_message",
387        "sarah_interrupt_turn",
388      ],
389      dataRoot,
390      activeRunLimit: 8,
391    })
392    continue
393  }
394  if (request.generation !== generation) {
395    respond(request.id, generation, false, undefined, {
396      code: "stale_generation",
397      message: `Expected generation ${generation}, got ${request.generation}.`,
398    })
399    continue
400  }
401  if (request.method === "health") {
402    if (oversizedHealthResponse) {
403      respond(request.id, generation, true, {
404        padding: "x".repeat(64 * 1024),
405      })
406      continue
407    }
408    if (hostRequestHealth || unavailableHostRequestHealth || staleHostRequestHealth) {
409      const mode = staleHostRequestHealth
410        ? "stale"
411        : unavailableHostRequestHealth
412          ? "unavailable"
413          : "success"
414      const hostGeneration = mode === "stale" ? generation - 1 : generation
415      const hostId = `host.${hostGeneration}.fixture`
416      pendingHostHealth = { request, hostId, hostGeneration, mode }
417      process.stdout.write(
418        `${JSON.stringify({
419          schema,
420          kind: "host_request",
421          id: hostId,
422          generation: hostGeneration,
423          method: "resolve_workspace",
424          params: { expectedWorkspaceRef: "workspace.omega.supervised" },
425        })}\n`,
426      )
427      continue
428    }
429    respond(request.id, staleHealthResponse ? generation - 1 : generation, true, healthResult())
430    continue
431  }
432  if (request.method === "list_runs") {
433    respond(request.id, generation, true, { runs: listRuns() })
434    continue
435  }
436  if (request.method === "get_run") {
437    const run = loadRuns().find((row) => row.runRef === request.params?.runRef)
438    if (!run) {
439      respond(request.id, generation, false, undefined, {
440        code: "run_not_found",
441        message: "No Full Auto run exists for that runRef.",
442      })
443      continue
444    }
445    respond(request.id, generation, true, { run: detail(run) })
446    continue
447  }
448  if (request.method === "start") {
449    const params = request.params ?? {}
450    if (!params.workspaceRef || !params.title || !params.objective || !params.doneCondition) {
451      respond(request.id, generation, false, undefined, {
452        code: "invalid_request",
453        message: "start requires workspaceRef, title, objective, and doneCondition.",
454      })
455      continue
456    }
457    if (params.rebaseUnsafe === true) {
458      respond(request.id, generation, false, undefined, {
459        code: "invalid_request",
460        message: "rebase_unsafe: refusing to start Full Auto on a rebase-unsafe worktree.",
461      })
462      continue
463    }
464    const now = new Date().toISOString()
465    const run = {
466      runRef: `run.full-auto.fixture.${Date.now().toString(36)}`,
467      threadRef: `thread.omega.${Date.now().toString(36)}`,
468      state: "running",
469      title: params.title,
470      objective: params.objective,
471      doneCondition: params.doneCondition,
472      workspaceRef: params.workspaceRef,
473      lane: params.lane ?? "codex-local",
474      turnCap: params.turnCap ?? 40,
475      successfulAttempts: 0,
476      failedAttempts: 0,
477      stallCause: null,
478      recoveryAction: "none",
479      terminalReason: null,
480      updatedAt: now,
481      turns: [],
482    }
483    const runs = loadRuns()
484    runs.push(run)
485    saveRuns(runs)
486    if (params.projectRef && params.worktreeRef) {
487      const bindings = loadBindings()
488      bindings.push({
489        runRef: run.runRef,
490        workspaceRef: params.workspaceRef,
491        projectRef: params.projectRef,
492        worktreeRef: params.worktreeRef,
493        worktreePathDigest: params.worktreePathDigest ?? null,
494        gitHead: params.gitHead ?? null,
495        rebaseUnsafe: false,
496        boundAt: now,
497      })
498      saveBindings(bindings)
499    }
500    respond(request.id, generation, true, { run: detail(run) })
501    continue
502  }
503  if (["pause", "resume", "stop", "retry"].includes(request.method)) {
504    const runs = loadRuns()
505    const index = runs.findIndex((row) => row.runRef === request.params?.runRef)
506    if (index < 0) {
507      respond(request.id, generation, false, undefined, {
508        code: "run_not_found",
509        message: "No Full Auto run exists for that runRef.",
510      })
511      continue
512    }
513    const nextState =
514      request.method === "pause"
515        ? "paused"
516        : request.method === "resume"
517          ? "running"
518          : request.method === "stop"
519            ? "stopped"
520            : "retrying"
521    runs[index] = {
522      ...runs[index],
523      state: nextState,
524      updatedAt: new Date().toISOString(),
525    }
526    saveRuns(runs)
527    respond(request.id, generation, true, { run: detail(runs[index]) })
528    continue
529  }
530  if (request.method === "handoff") {
531    const runs = loadRuns()
532    const index = runs.findIndex((row) => row.runRef === request.params?.runRef)
533    if (index < 0) {
534      respond(request.id, generation, false, undefined, {
535        code: "run_not_found",
536        message: "No Full Auto run exists for that runRef.",
537      })
538      continue
539    }
540    if (runs[index].state !== "paused") {
541      respond(request.id, generation, false, undefined, {
542        code: "invalid_request",
543        message: "A provider handoff is legal only while paused.",
544      })
545      continue
546    }
547    const targetLaneRef = request.params?.targetLaneRef
548    if (!["codex-local", "claude-local"].includes(targetLaneRef)) {
549      respond(request.id, generation, false, undefined, {
550        code: "invalid_request",
551        message: "That provider lane is not registered.",
552      })
553      continue
554    }
555    runs[index] = {
556      ...runs[index],
557      lane: targetLaneRef,
558      updatedAt: new Date().toISOString(),
559    }
560    saveRuns(runs)
561    respond(request.id, generation, true, {
562      run: detail(runs[index]),
563      transition: {
564        from: targetLaneRef === "claude-local" ? "codex-local" : "claude-local",
565        to: targetLaneRef,
566        disposition: "complete_within_bounds",
567      },
568    })
569    continue
570  }
571  if (request.method === "get_capacity") {
572    respond(request.id, generation, true, {
573      activeRunLimit: 8,
574      activeRunCount: listRuns().filter((run) =>
575        ["running", "pausing", "paused", "retrying", "stalled"].includes(run.state),
576      ).length,
577      lanes: [
578        { lane: "codex-local", state: "available", activeRuns: 0, reason: "ready and idle" },
579        { lane: "claude-local", state: "available", activeRuns: 0, reason: "ready and idle" },
580      ],
581      accounts: [
582        { accountRef: "account.codex.fixture", provider: "openai", label: "ChatGPT fixture", state: "ready", quotaState: "available", lane: "codex-local" },
583        { accountRef: "account.claude.fixture", provider: "anthropic", label: "Claude fixture", state: "ready", quotaState: "available", lane: "claude-local" },
584      ],
585      nonOverridableGuardrails: [
586        "workspace_binding",
587        "own_capacity_only",
588        "no_rate_limit_reset_triggering",
589      ],
590      ownerConfigurableGuardrails: [
591        "maxWallClockMs",
592        "maxTurns",
593        "maxPerTurnFailures",
594        "tokenBudgetRef",
595      ],
596      enabledThreadsNeverEvicted: true,
597    })
598    continue
599  }
600  if (request.method === "decide_attention") {
601    const run = loadRuns().find((row) => row.runRef === request.params?.runRef)
602    if (!run) {
603      respond(request.id, generation, false, undefined, {
604        code: "run_not_found",
605        message: "No Full Auto run exists for that runRef.",
606      })
607      continue
608    }
609    const state = run.state
610    if (state !== "stalled" && state !== "retrying") {
611      respond(request.id, generation, true, { attention: null })
612      continue
613    }
614    const dedupKey = `${run.runRef}:${state}:${run.stallCause ?? "none"}`
615    if (request.params?.previousDedupKey === dedupKey) {
616      respond(request.id, generation, true, { attention: null })
617      continue
618    }
619    respond(request.id, generation, true, {
620      attention: {
621        notify: request.params?.permissionGranted === true,
622        dedupKey,
623        title: `Full Auto ${state}`,
624        body: `${run.title} needs attention (${state}).`,
625      },
626    })
627    continue
628  }
629  if (request.method === "get_report") {
630    const run = loadRuns().find((row) => row.runRef === request.params?.runRef)
631    if (!run) {
632      respond(request.id, generation, false, undefined, {
633        code: "run_not_found",
634        message: "No Full Auto run exists for that runRef.",
635      })
636      continue
637    }
638    respond(request.id, generation, true, {
639      report: {
640        schema: "openagents.desktop.full_auto_run_report.v1",
641        runRef: run.runRef,
642        title: run.title,
643        objective: run.objective,
644        doneCondition: run.doneCondition,
645        state: run.state,
646        turns: run.turns ?? [],
647        evidence: {
648          objectiveRef: `objective.${run.runRef}`,
649          turnRef: `turn.${run.runRef}.latest`,
650          changeRef: `change.${run.runRef}.latest`,
651          projectGeneration: "project.generation.fixture.1",
652          diffSummary: "2 files changed, 18 insertions, 3 deletions",
653          testCommand: "cargo test -p full_auto_ui",
654          testOutcome: "passed",
655          verificationRef: `verification.host.${run.runRef}.latest`,
656          hostExecuted: true,
657        },
658      },
659    })
660    continue
661  }
662  if (request.method === "get_receipt") {
663    const run = loadRuns().find((row) => row.runRef === request.params?.runRef)
664    if (!run) {
665      respond(request.id, generation, false, undefined, {
666        code: "run_not_found",
667        message: "No Full Auto run exists for that runRef.",
668      })
669      continue
670    }
671    respond(request.id, generation, true, {
672      receipt: {
673        schema: "openagents.desktop.full_auto_run_receipt.v1",
674        runRef: run.runRef,
675        objectiveDigest: "fixture-objective-digest",
676        doneConditionDigest: "fixture-done-digest",
677        objectiveRevisionCount: 1,
678        turnCount: (run.turns ?? []).length,
679        state: run.state,
680        objectiveRef: `objective.${run.runRef}`,
681        turnRef: `turn.${run.runRef}.latest`,
682        changeRef: `change.${run.runRef}.latest`,
683        verificationRef: `verification.host.${run.runRef}.latest`,
684        authorityReceiptRef: `receipt.authority.${run.runRef}.latest`,
685        decisionRef: `decision.authority.${run.runRef}.latest`,
686        allowed: true,
687      },
688    })
689    continue
690  }
691  if (request.method === "apply_control_intent") {
692    const params = request.params ?? {}
693    if (!params.intentId || !params.runRef || !["pause", "resume", "stop"].includes(params.action)) {
694      respond(request.id, generation, false, undefined, {
695        code: "invalid_request",
696        message: "apply_control_intent requires intentId, runRef, and action pause|resume|stop.",
697      })
698      continue
699    }
700    const runs = loadRuns()
701    const index = runs.findIndex((row) => row.runRef === params.runRef)
702    if (index < 0) {
703      respond(request.id, generation, true, {
704        outcome: {
705          intentId: params.intentId,
706          status: "rejected",
707          rejectionReason: "run_not_found",
708        },
709      })
710      continue
711    }
712    const nextState =
713      params.action === "pause" ? "paused" : params.action === "resume" ? "running" : "stopped"
714    runs[index] = { ...runs[index], state: nextState, updatedAt: new Date().toISOString() }
715    saveRuns(runs)
716    respond(request.id, generation, true, {
717      outcome: {
718        intentId: params.intentId,
719        status: "applied",
720        resultLifecycleState: nextState,
721      },
722    })
723    continue
724  }
725  if (request.method === "get_sync_status") {
726    respond(request.id, generation, true, {
727      available: false,
728      publishBlocksDispatch: false,
729      reason: "omega_khala_sync_session_unavailable",
730    })
731    continue
732  }
733  if (request.method === "publish_projection") {
734    respond(request.id, generation, true, {
735      ok: false,
736      status: "sync_unavailable",
737      reason: "omega_khala_sync_session_unavailable",
738    })
739    continue
740  }
741  if (request.method === "get_native_binding") {
742    const run = loadRuns().find((row) => row.runRef === request.params?.runRef)
743    if (!run) {
744      respond(request.id, generation, false, undefined, {
745        code: "run_not_found",
746        message: "No Full Auto run exists for that runRef.",
747      })
748      continue
749    }
750    const binding = loadBindings().find((row) => row.runRef === run.runRef) ?? null
751    respond(request.id, generation, true, { binding })
752    continue
753  }
754  if (request.method === "assess_native_boundary") {
755    const run = loadRuns().find((row) => row.runRef === request.params?.runRef)
756    if (!run) {
757      respond(request.id, generation, false, undefined, {
758        code: "run_not_found",
759        message: "No Full Auto run exists for that runRef.",
760      })
761      continue
762    }
763    const binding = loadBindings().find((row) => row.runRef === run.runRef) ?? null
764    if (!binding) {
765      respond(request.id, generation, true, {
766        assessment: {
767          ok: false,
768          reason: "missing_binding",
769          message: "No native project/worktree binding exists for this Full Auto run.",
770        },
771      })
772      continue
773    }
774    if (binding.workspaceRef !== run.workspaceRef) {
775      respond(request.id, generation, true, {
776        assessment: {
777          ok: false,
778          reason: "workspace_mismatch",
779          message: "The bound workspace does not match the currently resolved workspace.",
780        },
781      })
782      continue
783    }
784    if (binding.rebaseUnsafe) {
785      respond(request.id, generation, true, {
786        assessment: {
787          ok: false,
788          reason: "rebase_unsafe",
789          message: "The bound worktree is rebase-unsafe; Full Auto refuses to continue.",
790        },
791      })
792      continue
793    }
794    respond(request.id, generation, true, {
795      assessment: {
796        ok: true,
797        evidence: {
798          projectRef: binding.projectRef,
799          worktreeRef: binding.worktreeRef,
800          worktreePathDigest: binding.worktreePathDigest ?? null,
801          gitHead: binding.gitHead ?? null,
802        },
803      },
804    })
805    continue
806  }
807  if (request.method === "start_agent_computer_session") {
808    const params = request.params ?? {}
809    if (
810      typeof params.bearerToken !== "string" ||
811      typeof params.controlPlaneBaseUrl !== "string" ||
812      typeof params.repoRef !== "string" ||
813      typeof params.objective !== "string"
814    ) {
815      respond(request.id, generation, false, undefined, {
816        code: "invalid_request",
817        message:
818          "start_agent_computer_session requires bearerToken, controlPlaneBaseUrl, repoRef, and objective.",
819      })
820      continue
821    }
822    const sessions = loadAgentComputerSessions()
823    const session = projectAgentComputerSession(params, "queued")
824    sessions.push(session)
825    saveAgentComputerSessions(sessions)
826    respond(request.id, generation, true, { session })
827    continue
828  }
829  if (request.method === "refresh_agent_computer_session") {
830    const params = request.params ?? {}
831    const sessions = loadAgentComputerSessions()
832    const index = sessions.findIndex((row) => row.sessionRef === params.sessionRef)
833    if (index === -1) {
834      respond(request.id, generation, false, undefined, {
835        code: "invalid_request",
836        message: "No Agent Computer session exists for that sessionRef.",
837      })
838      continue
839    }
840    const next = {
841      ...sessions[index],
842      state: "running",
843      updatedAt: new Date().toISOString(),
844    }
845    sessions[index] = next
846    saveAgentComputerSessions(sessions)
847    respond(request.id, generation, true, { session: next })
848    continue
849  }
850  if (request.method === "run_agent_computer_turn") {
851    const params = request.params ?? {}
852    if (
853      typeof params.bearerToken !== "string" ||
854      typeof params.controlPlaneBaseUrl !== "string" ||
855      typeof params.repoRef !== "string" ||
856      typeof params.objective !== "string"
857    ) {
858      respond(request.id, generation, false, undefined, {
859        code: "invalid_request",
860        message:
861          "run_agent_computer_turn requires bearerToken, controlPlaneBaseUrl, repoRef, and objective.",
862      })
863      continue
864    }
865    const sessions = loadAgentComputerSessions()
866    const session = projectAgentComputerSession(params, "completed")
867    sessions.push(session)
868    saveAgentComputerSessions(sessions)
869    respond(request.id, generation, true, {
870      session,
871      finishReason: "stop",
872      eventKinds: ["turn.started", "text.delta", "turn.finished"],
873    })
874    continue
875  }
876  if (request.method === "get_agent_computer_session") {
877    const session =
878      loadAgentComputerSessions().find((row) => row.sessionRef === request.params?.sessionRef) ??
879      null
880    respond(request.id, generation, true, { session })
881    continue
882  }
883  if (request.method === "list_agent_computer_sessions") {
884    respond(request.id, generation, true, { sessions: loadAgentComputerSessions() })
885    continue
886  }
887  // SARAH-NR-06: Nostr conversation methods (mock transport; no Khala Sync).
888  if (request.method === "sarah_session_status") {
889    respond(request.id, generation, true, sarahSessionStatus())
890    continue
891  }
892  if (request.method === "sarah_bootstrap") {
893    respond(request.id, generation, true, sarahBootstrap())
894    continue
895  }
896  if (request.method === "sarah_room_snapshot") {
897    respond(request.id, generation, true, sarahRoomSnapshot(request.params ?? {}))
898    continue
899  }
900  if (request.method === "sarah_send_message") {
901    const text = request.params?.text
902    if (typeof text !== "string" || text.trim().length === 0) {
903      respond(request.id, generation, false, undefined, {
904        code: "invalid_request",
905        message: "sarah_send_message requires text.",
906      })
907      continue
908    }
909    if (/bearer\s|sk-|authorization:/i.test(text)) {
910      respond(request.id, generation, false, undefined, {
911        code: "invalid_request",
912        message: "message must not carry raw credentials.",
913      })
914      continue
915    }
916    respond(request.id, generation, true, sarahSendMessage(text))
917    continue
918  }
919  if (request.method === "sarah_interrupt_turn") {
920    const turnRef = request.params?.turnRef
921    if (typeof turnRef !== "string" || turnRef.trim().length === 0) {
922      respond(request.id, generation, false, undefined, {
923        code: "invalid_request",
924        message: "sarah_interrupt_turn requires turnRef.",
925      })
926      continue
927    }
928    respond(request.id, generation, true, sarahInterruptTurn(turnRef))
929    continue
930  }
931  respond(request.id, generation, false, undefined, {
932    code: "unknown_method",
933    message: `Unknown method ${request.method}.`,
934  })
935}
936
Served at tenant.openagents/omega Member data and write actions are omitted.