@astrosheep/keiyaku 4.5.28 → 4.5.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/build/src/akuma/akuma-handle.d.ts +7 -0
  2. package/build/src/akuma/akuma-handle.js +19 -6
  3. package/build/src/akuma/akuma-instance.d.ts +0 -1
  4. package/build/src/akuma/akuma-instance.js +2 -4
  5. package/build/src/akuma/akuma-observe.js +0 -1
  6. package/build/src/akuma/akuma-product.d.ts +4 -8
  7. package/build/src/akuma/akuma-product.js +3 -20
  8. package/build/src/akuma/akuma.d.ts +0 -8
  9. package/build/src/akuma/akuma.js +0 -5
  10. package/build/src/akuma/archetype.d.ts +6 -6
  11. package/build/src/akuma/archetype.js +18 -28
  12. package/build/src/akuma/body.d.ts +4 -26
  13. package/build/src/akuma/body.js +18 -2
  14. package/build/src/akuma/call-initial-tell.d.ts +55 -0
  15. package/build/src/akuma/call-initial-tell.js +32 -0
  16. package/build/src/akuma/call-input.d.ts +0 -3
  17. package/build/src/akuma/call-input.js +0 -7
  18. package/build/src/akuma/call-request.d.ts +13 -10
  19. package/build/src/akuma/call-request.js +26 -14
  20. package/build/src/akuma/fleet-execution.d.ts +13 -1
  21. package/build/src/akuma/fleet-execution.js +67 -14
  22. package/build/src/akuma/fleet-observation.d.ts +26 -18
  23. package/build/src/akuma/fleet-observation.js +7 -1
  24. package/build/src/akuma/heart/facts.d.ts +2 -3
  25. package/build/src/akuma/heart/soul.js +1 -6
  26. package/build/src/akuma/projection-read.js +1 -2
  27. package/build/src/akuma/provider-recipe.d.ts +0 -10
  28. package/build/src/akuma/provider-recipe.js +0 -23
  29. package/build/src/akuma/provider.d.ts +1 -2
  30. package/build/src/akuma/providers/acp/index.js +0 -11
  31. package/build/src/akuma/providers/claude/index.js +2 -14
  32. package/build/src/akuma/providers/codex-app-server/index.js +0 -22
  33. package/build/src/akuma/providers/grok-build/index.js +0 -11
  34. package/build/src/akuma/providers/opencode-sdk/index.js +0 -10
  35. package/build/src/akuma/providers/pi/index.js +1 -5
  36. package/build/src/akuma/requests.d.ts +0 -1
  37. package/build/src/akuma/requests.js +0 -7
  38. package/build/src/akuma/turn-drive.d.ts +3 -0
  39. package/build/src/akuma/turn-drive.js +2 -2
  40. package/build/src/{library → cli}/catalog.d.ts +7 -30
  41. package/build/src/cli/catalog.js +1 -0
  42. package/build/src/cli/commands/akuma-invoke.d.ts +3 -3
  43. package/build/src/cli/commands/akuma-invoke.js +70 -97
  44. package/build/src/cli/commands/akuma.js +28 -21
  45. package/build/src/cli/commands/bind.js +4 -5
  46. package/build/src/cli/commands/contract-help.d.ts +21 -18
  47. package/build/src/cli/commands/contract-help.js +44 -84
  48. package/build/src/cli/commands/contract-invoke.js +6 -6
  49. package/build/src/cli/commands/contract.d.ts +1 -1
  50. package/build/src/cli/commands/contract.js +1 -6
  51. package/build/src/cli/commands/install.d.ts +1 -1
  52. package/build/src/cli/commands/install.js +1 -1
  53. package/build/src/cli/commands/nuke.js +2 -2
  54. package/build/src/cli/commands/task.js +48 -16
  55. package/build/src/cli/invoke.js +48 -11
  56. package/build/src/cli/parse.js +2 -0
  57. package/build/src/cli/render/akuma-activity.d.ts +42 -11
  58. package/build/src/cli/render/akuma-activity.js +307 -125
  59. package/build/src/cli/render/akuma-tool.d.ts +7 -1
  60. package/build/src/cli/render/akuma-tool.js +35 -23
  61. package/build/src/cli/render/akuma.d.ts +5 -9
  62. package/build/src/cli/render/akuma.js +68 -98
  63. package/build/src/cli/render/audit.js +2 -2
  64. package/build/src/cli/render/catalog.d.ts +1 -1
  65. package/build/src/cli/render/catalog.js +1 -0
  66. package/build/src/cli/render/contract.js +3 -3
  67. package/build/src/cli/render/kanshi.js +2 -2
  68. package/build/src/cli/render/receipt.js +4 -4
  69. package/build/src/cli/render/refusal.js +2 -2
  70. package/build/src/cli/render/settings.js +2 -2
  71. package/build/src/cli/render/task.js +2 -2
  72. package/build/src/cli/render/terminal.d.ts +5 -0
  73. package/build/src/cli/render/terminal.js +13 -0
  74. package/build/src/cli/result.d.ts +1 -1
  75. package/build/src/cli/runtime.js +10 -4
  76. package/build/src/cli/selectors.js +2 -2
  77. package/build/src/index.d.ts +1 -0
  78. package/build/src/index.js +1 -0
  79. package/build/src/library/akuma-creation.d.ts +28 -15
  80. package/build/src/library/akuma-creation.js +141 -107
  81. package/build/src/library/akumas.d.ts +42 -0
  82. package/build/src/library/akumas.js +61 -0
  83. package/build/src/library/composition.d.ts +14 -402
  84. package/build/src/library/composition.js +24 -25
  85. package/build/src/library/contract-handle.d.ts +7 -2
  86. package/build/src/library/contract-handle.js +14 -2
  87. package/build/src/library/contract-types.d.ts +9 -2
  88. package/build/src/library/contract.d.ts +8 -15
  89. package/build/src/library/contract.js +21 -39
  90. package/build/src/library/fleet.js +12 -12
  91. package/build/src/library/keiyaku.d.ts +8 -424
  92. package/build/src/library/keiyaku.js +3 -17
  93. package/build/src/runtime/proc/windows-launch.exe +0 -0
  94. package/package.json +5 -1
  95. package/build/src/akuma/akuma-product-symbols.d.ts +0 -1
  96. package/build/src/akuma/akuma-product-symbols.js +0 -1
  97. package/build/src/library/catalog.js +0 -130
@@ -0,0 +1,32 @@
1
+ import { defaultWaitComplete, bornStatus, readWaitComplete, waitForObservation } from "./akuma-observe.js";
2
+ import { recordTell } from "./heart/index.js";
3
+ import { pathsForAkuId } from "./identity.js";
4
+ import { BIRTH_TIMEOUT_MS } from "./publication.js";
5
+ export async function admitCallInitialTell(input) {
6
+ const paths = pathsForAkuId(input.world, input.id);
7
+ const birth = await waitForObservation({
8
+ timeoutMs: BIRTH_TIMEOUT_MS,
9
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
10
+ probe: async () => await readWaitComplete(input.world, input.id),
11
+ observe: async () => (await bornStatus(paths, input.id, { aperture: "receipt" })).status,
12
+ complete: defaultWaitComplete,
13
+ });
14
+ if (birth.reason !== "completed" || birth.value.life !== "asleep") {
15
+ return {
16
+ kind: "birth-failed",
17
+ diagnostic: `Akuma ${input.id} prompt-free birth did not settle cleanly`,
18
+ };
19
+ }
20
+ input.signal?.throwIfAborted();
21
+ const recorded = await recordTell(paths, {
22
+ kind: "tell",
23
+ id: input.initialTell.tellId,
24
+ body: input.initialTell.body,
25
+ recordedAt: input.now?.() ?? new Date().toISOString(),
26
+ ...(input.initialTell.schemaJson === undefined ? {} : { schemaJson: input.initialTell.schemaJson }),
27
+ ...(input.initialTell.initiator === undefined ? {} : { initiator: input.initialTell.initiator }),
28
+ });
29
+ if (recorded.kind === "not-born")
30
+ return recorded;
31
+ return { kind: "admitted", tell: recorded.tell, wake: input.wake(recorded.tell) };
32
+ }
@@ -1,4 +1 @@
1
- export declare function callReadonly(value: unknown, diagnostic?: string): Readonly<{
2
- readonly?: true;
3
- }>;
4
1
  export declare function canonicalBirthCwd(input: string, diagnostic?: string): Promise<string>;
@@ -1,12 +1,5 @@
1
1
  import { realpath, stat } from "node:fs/promises";
2
2
  import { resolve } from "node:path";
3
- export function callReadonly(value, diagnostic = "Akuma call readonly must be true") {
4
- if (value === undefined)
5
- return {};
6
- if (value !== true)
7
- throw new TypeError(diagnostic);
8
- return { readonly: true };
9
- }
10
3
  export async function canonicalBirthCwd(input, diagnostic = `cwd is not an existing directory: ${input}`) {
11
4
  const selected = resolve(input);
12
5
  try {
@@ -1,5 +1,6 @@
1
1
  import { type Soul } from "./heart/index.js";
2
2
  import { type AkuId, type AkumaPaths } from "./identity.js";
3
+ import type { CallInitialTell, CallInitialTellAdmission } from "./call-initial-tell.js";
3
4
  import { type ChildRequestCommand, type ErasedRequestCommand, type RequestProtocol } from "./request-wire.js";
4
5
  import type { OwnedProcess } from "../runtime/proc/run.js";
5
6
  import { z } from "zod";
@@ -17,19 +18,20 @@ declare const akumaCallRecipeSchema: z.ZodObject<{
17
18
  options: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
18
19
  model?: string;
19
20
  effort?: string;
20
- readonly?: true;
21
21
  network?: "disabled" | "enabled";
22
- sandbox?: "full-access";
23
22
  systemPrompt?: string;
24
23
  systemPromptMode?: import("./provider-recipe.js").SystemPromptMode;
25
24
  }>, unknown>>;
26
- readonly: z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("./provider-recipe.js").ReadonlyRestraint, unknown>>>;
27
25
  }, z.core.$strict>;
28
26
  declare const akumaCallPayloadSchema: z.ZodObject<{
29
27
  world: z.ZodString;
30
28
  archetype: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
31
- body: z.ZodOptional<z.ZodString>;
32
- initiator: z.ZodOptional<z.ZodString>;
29
+ initialTell: z.ZodObject<{
30
+ tellId: z.ZodString;
31
+ body: z.ZodString;
32
+ schemaJson: z.ZodOptional<z.ZodString>;
33
+ initiator: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strict>;
33
35
  cwd: z.ZodOptional<z.ZodString>;
34
36
  recipe: z.ZodObject<{
35
37
  description: z.ZodOptional<z.ZodString>;
@@ -44,13 +46,10 @@ declare const akumaCallPayloadSchema: z.ZodObject<{
44
46
  options: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
45
47
  model?: string;
46
48
  effort?: string;
47
- readonly?: true;
48
49
  network?: "disabled" | "enabled";
49
- sandbox?: "full-access";
50
50
  systemPrompt?: string;
51
51
  systemPromptMode?: import("./provider-recipe.js").SystemPromptMode;
52
52
  }>, unknown>>;
53
- readonly: z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("./provider-recipe.js").ReadonlyRestraint, unknown>>>;
54
53
  }, z.core.$strict>;
55
54
  }, z.core.$strict>;
56
55
  export type AkumaCallRecipe = z.infer<typeof akumaCallRecipeSchema>;
@@ -60,14 +59,18 @@ export type AkumaCallRequest = z.infer<typeof akumaCallPayloadSchema> & Readonly
60
59
  export type AkumaCallRequestChildLaunch = Readonly<{
61
60
  paths: AkumaPaths;
62
61
  seed: Omit<Soul, "createdAt">;
63
- initialBody?: string;
64
- initiator?: string;
62
+ }>;
63
+ export type InitialTellAdmissionRequest = Readonly<{
64
+ id: AkuId;
65
+ initialTell: CallInitialTell;
66
+ signal: AbortSignal;
65
67
  }>;
66
68
  type AkumaCallRequestCapabilities = Readonly<{
67
69
  world: WorldRoot;
68
70
  paths: AkumaPaths;
69
71
  parent: Soul;
70
72
  spawn(launch: AkumaCallRequestChildLaunch): Promise<OwnedProcess | void>;
73
+ admitInitialTell(input: InitialTellAdmissionRequest): Promise<CallInitialTellAdmission>;
71
74
  }>;
72
75
  export declare function decodeAkumaCallRequest(value: unknown): AkumaCallRequest | null;
73
76
  export declare function akumaCallRequestProtocol(): RequestProtocol<AkumaCallRequest, AkuId, AkuId>;
@@ -3,7 +3,7 @@ import { clipAllowedActions, decodeAllowedActions } from "./allowed.js";
3
3
  import { refuseRequest, reserveRequest } from "./heart/index.js";
4
4
  import { archetypeName, parseAkuId } from "./identity.js";
5
5
  import { publishAkuma } from "./publication.js";
6
- import { decodeProviderOptions, decodeReadonlyRestraint } from "./provider-recipe.js";
6
+ import { decodeProviderOptions } from "./provider-recipe.js";
7
7
  import { decodeProviderExecution, resolveProviderExecution } from "./providers/index.js";
8
8
  import { requestBodyCommand } from "./request-rendezvous.js";
9
9
  import { eraseRequestCommand, } from "./request-wire.js";
@@ -47,27 +47,27 @@ const archetypeSchema = z.string().transform((value, context) => {
47
47
  const allowedActionsSchema = schemaDecode(decodeAllowedActions, "expected allowed actions");
48
48
  const providerExecutionSchema = schemaDecode(decodeProviderExecution, "expected provider execution");
49
49
  const providerOptionsSchema = schemaDecode(decodeProviderOptions, "expected provider options");
50
- const readonlyRestraintSchema = schemaDecode(decodeReadonlyRestraint, "expected readonly restraint");
51
50
  const akumaCallRecipeSchema = z
52
51
  .object({
53
52
  description: z.string().trim().min(1).optional(),
54
53
  allowed: allowedActionsSchema,
55
54
  provider: providerExecutionSchema,
56
55
  options: providerOptionsSchema,
57
- readonly: readonlyRestraintSchema.optional(),
58
56
  })
59
- .strict()
60
- .superRefine((recipe, context) => {
61
- if ((recipe.options.readonly === true) !== (recipe.readonly !== undefined)) {
62
- context.addIssue({ code: "custom", message: "readonly recipe fields disagree" });
63
- }
64
- });
57
+ .strict();
58
+ const initialTellSchema = z
59
+ .object({
60
+ tellId: z.string().trim().min(1),
61
+ body: z.string(),
62
+ schemaJson: z.string().trim().min(1).optional(),
63
+ initiator: z.string().min(1).optional(),
64
+ })
65
+ .strict();
65
66
  const akumaCallPayloadSchema = z
66
67
  .object({
67
68
  world: absolutePathSchema,
68
69
  archetype: archetypeSchema,
69
- body: z.string().optional(),
70
- initiator: z.string().min(1).optional(),
70
+ initialTell: initialTellSchema,
71
71
  cwd: absolutePathSchema.optional(),
72
72
  recipe: akumaCallRecipeSchema,
73
73
  })
@@ -98,7 +98,6 @@ async function executeAkumaCall(request, facts, capabilities) {
98
98
  allowed: clipAllowedActions(request.recipe.allowed, parent.allowed),
99
99
  provider: selected.execution,
100
100
  options: admission.options,
101
- ...(admission.readonly === undefined ? {} : { readonly: admission.readonly }),
102
101
  };
103
102
  const published = await publishAkuma({
104
103
  worldPath: world,
@@ -117,11 +116,24 @@ async function executeAkumaCall(request, facts, capabilities) {
117
116
  cwd: request.cwd ?? parent.cwd,
118
117
  origin: { kind: "request", parent: parent.id, requestId: facts.id },
119
118
  },
120
- ...(request.body === undefined ? {} : { initialBody: request.body }),
121
- ...(request.initiator === undefined ? {} : { initiator: request.initiator }),
122
119
  });
123
120
  },
124
121
  });
122
+ const admitted = await capabilities.admitInitialTell({
123
+ id: published.id,
124
+ initialTell: {
125
+ tellId: request.initialTell.tellId,
126
+ body: request.initialTell.body,
127
+ ...(request.initialTell.schemaJson === undefined ? {} : { schemaJson: request.initialTell.schemaJson }),
128
+ ...(request.initialTell.initiator === undefined ? {} : { initiator: request.initialTell.initiator }),
129
+ },
130
+ signal: facts.signal,
131
+ });
132
+ if (admitted.kind === "birth-failed")
133
+ throw new Error(admitted.diagnostic);
134
+ if (admitted.kind === "not-born")
135
+ throw new Error(`Akuma ${published.id} was not born for its initial Tell`);
136
+ await admitted.wake;
125
137
  return { result: published.id, child: published.id };
126
138
  }
127
139
  export function akumaCallRequestProtocol() {
@@ -1,10 +1,11 @@
1
+ import type { Schema } from "./schema.js";
1
2
  import { type AkumaStatus, type TellResult } from "./akuma.js";
2
3
  import { type LiveStatusObservation } from "./akuma-observe.js";
3
4
  import type { ActivityRow } from "./projection.js";
4
5
  import { type DispatchAssociation } from "./dispatch-association.js";
5
6
  import type { AkumaAlias } from "../identity/selector.js";
6
7
  import type { WorldRoot } from "../world.js";
7
- import { type AkumaKillResult, type AkumaTellResult, type AkumaTellWaitResult, type AkumaWaitResult } from "./fleet-observation.js";
8
+ import { type AkumaKillResult, type AkumaTellResult, type AkumaTellWaitObservation, type AkumaTellWaitResult, type AkumaWaitResult } from "./fleet-observation.js";
8
9
  export type WaitIdentityFacts = Readonly<{
9
10
  /** The alias currently addressing this Akuma in its world, when one is bound to it. */
10
11
  alias?: AkumaAlias;
@@ -56,6 +57,17 @@ export type TellExecutionInput = Readonly<{
56
57
  onObserve?: TellWaitObserver;
57
58
  }>;
58
59
  export declare function executeTellAkuma(input: TellExecutionInput): Promise<AkumaTellResult>;
60
+ export declare function decodeTellWaitObservation(observation: AkumaTellWaitObservation, schema: Schema<unknown>): AkumaTellWaitObservation;
61
+ export declare function observeAdmittedTellWaitAkuma(input: Readonly<{
62
+ path: WorldRoot;
63
+ id: AkumaStatus["id"];
64
+ tellId: string;
65
+ timeoutMs: number;
66
+ signal?: AbortSignal;
67
+ startedAt?: number;
68
+ wake?: Promise<TellResult>;
69
+ onObserve?: TellWaitObserver;
70
+ }>): Promise<AkumaTellWaitResult>;
59
71
  export declare function executeTellWaitAkuma(input: TellExecutionInput & Readonly<{
60
72
  timeoutMs: number;
61
73
  schemaJson?: string;
@@ -1,4 +1,4 @@
1
- import { AkumaDecodeError, AkumaProviderError } from "./akuma-errors.js";
1
+ import { AkumaProviderError } from "./akuma-errors.js";
2
2
  import { AkumaNotBornError, defaultWaitComplete } from "./akuma.js";
3
3
  import { createAkumaProduct } from "./akuma-product.js";
4
4
  import { readLiveStatus, waitForObservation } from "./akuma-observe.js";
@@ -133,7 +133,65 @@ function tellWaitObservation(observed) {
133
133
  return { reason: "answered", answer: observed.outcome.answerJson ?? observed.outcome.answer };
134
134
  if (observed.outcome.kind === "failed")
135
135
  return { reason: "failed", diagnostic: observed.outcome.diagnostic };
136
- throw new AkumaDecodeError(observed.outcome.diagnostic, observed.outcome.answer);
136
+ return {
137
+ reason: "invalid-output",
138
+ diagnostic: observed.outcome.diagnostic,
139
+ answer: observed.outcome.answer,
140
+ };
141
+ }
142
+ export function decodeTellWaitObservation(observation, schema) {
143
+ if (observation.reason !== "answered")
144
+ return observation;
145
+ let value = observation.answer;
146
+ if (typeof value === "string") {
147
+ try {
148
+ value = JSON.parse(value);
149
+ }
150
+ catch (error) {
151
+ return {
152
+ reason: "invalid-output",
153
+ diagnostic: error instanceof Error ? error.message : "Answer is not valid JSON",
154
+ answer: typeof observation.answer === "string" ? observation.answer : String(observation.answer),
155
+ };
156
+ }
157
+ }
158
+ try {
159
+ return { reason: "answered", answer: schema.decode(value) };
160
+ }
161
+ catch (error) {
162
+ return {
163
+ reason: "invalid-output",
164
+ diagnostic: error instanceof Error ? error.message : "Answer failed schema decode",
165
+ answer: typeof observation.answer === "string" ? observation.answer : String(observation.answer),
166
+ };
167
+ }
168
+ }
169
+ export async function observeAdmittedTellWaitAkuma(input) {
170
+ const handle = source(input.path).selectHandle({ id: input.id });
171
+ const tell = await handle.admittedReceipt(input.tellId);
172
+ await input.onObserve?.admitted?.(tell, input.id);
173
+ let settled;
174
+ void input.wake?.then((receipt) => {
175
+ settled = receipt;
176
+ }, () => undefined);
177
+ const admittedAt = Date.parse(tell.row.at);
178
+ const observedAt = performance.timeOrigin + performance.now();
179
+ const elapsed = input.startedAt === undefined
180
+ ? Number.isFinite(admittedAt)
181
+ ? Math.max(0, observedAt - admittedAt)
182
+ : 0
183
+ : Math.max(0, performance.now() - input.startedAt);
184
+ const observed = await handle.tellOutcome(input.tellId, {
185
+ timeoutMs: Math.max(0, input.timeoutMs - elapsed),
186
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
187
+ ...(input.onObserve?.observe === undefined ? {} : { observe: input.onObserve.observe }),
188
+ });
189
+ return fleetResultSchemas.tellWait.parse({
190
+ akuma: input.id,
191
+ tell: settled ?? tell,
192
+ observation: tellWaitObservation(observed),
193
+ completedAt: observed.completedAt,
194
+ });
137
195
  }
138
196
  export async function executeTellWaitAkuma(input) {
139
197
  input.signal?.throwIfAborted();
@@ -154,21 +212,16 @@ export async function executeTellWaitAkuma(input) {
154
212
  throw new AkumaProviderError(`Tell interrupt unavailable: ${admission.evidence}`);
155
213
  if (admission.kind === "not-born")
156
214
  throw new AkumaNotBornError(input.id);
157
- await input.onObserve?.admitted?.(await handle.admittedReceipt(admission.tell.id), input.id);
158
- // The wake runs behind the window; a settled wake is preferred, otherwise the
159
- // receipt reports the admitted Tell as it stands when the window closes.
160
- let settled;
161
- void admission.wake.then((receipt) => {
162
- settled = receipt;
163
- }, () => undefined);
164
- const observed = await handle.tellOutcome(admission.tell.id, {
215
+ return await observeAdmittedTellWaitAkuma({
216
+ path: input.path,
217
+ id: input.id,
218
+ tellId: admission.tell.id,
165
219
  timeoutMs: input.timeoutMs,
220
+ startedAt: performance.now(),
221
+ wake: admission.wake,
166
222
  ...(input.signal === undefined ? {} : { signal: input.signal }),
167
- ...(input.onObserve?.observe === undefined ? {} : { observe: input.onObserve.observe }),
223
+ ...(input.onObserve === undefined ? {} : { onObserve: input.onObserve }),
168
224
  });
169
- const observation = tellWaitObservation(observed);
170
- const tell = settled ?? (await handle.admittedReceipt(admission.tell.id));
171
- return fleetResultSchemas.tellWait.parse({ akuma: input.id, tell, observation });
172
225
  }
173
226
  export async function executeKillAkuma(input) {
174
227
  input.signal?.throwIfAborted();
@@ -29,12 +29,6 @@ declare const akumaObservationSchema: z.ZodObject<{
29
29
  "contract.deliver": "contract.deliver";
30
30
  "contract.review": "contract.review";
31
31
  }>>, z.ZodTransform<import("./allowed.js").AllowedActions, ("task.add" | "task.addDocument" | "task.compose" | "task.done" | "task.drop" | "task.hold" | "task.resume" | "task.start" | "task.stop" | "task.update" | "akuma.call" | "akuma.kill" | "akuma.tell" | "contract.audit" | "contract.deliver" | "contract.review")[]>>;
32
- readonly: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
33
- enforcement: z.ZodLiteral<"native">;
34
- }, z.core.$strict>, z.ZodObject<{
35
- enforcement: z.ZodLiteral<"none">;
36
- diagnostic: z.ZodString;
37
- }, z.core.$strict>]>>;
38
32
  timeline: z.ZodUnion<readonly [z.ZodObject<{
39
33
  reportedChanges: z.ZodReadonly<z.ZodArray<z.ZodObject<{
40
34
  sequence: z.ZodNumber;
@@ -501,12 +495,6 @@ declare const akumaWaitResultSchema: z.ZodObject<{
501
495
  "contract.deliver": "contract.deliver";
502
496
  "contract.review": "contract.review";
503
497
  }>>, z.ZodTransform<import("./allowed.js").AllowedActions, ("task.add" | "task.addDocument" | "task.compose" | "task.done" | "task.drop" | "task.hold" | "task.resume" | "task.start" | "task.stop" | "task.update" | "akuma.call" | "akuma.kill" | "akuma.tell" | "contract.audit" | "contract.deliver" | "contract.review")[]>>;
504
- readonly: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
505
- enforcement: z.ZodLiteral<"native">;
506
- }, z.core.$strict>, z.ZodObject<{
507
- enforcement: z.ZodLiteral<"none">;
508
- diagnostic: z.ZodString;
509
- }, z.core.$strict>]>>;
510
498
  timeline: z.ZodUnion<readonly [z.ZodObject<{
511
499
  reportedChanges: z.ZodReadonly<z.ZodArray<z.ZodObject<{
512
500
  sequence: z.ZodNumber;
@@ -1037,6 +1025,21 @@ declare const akumaTellResultSchema: z.ZodObject<{
1037
1025
  }>>]>;
1038
1026
  }, z.core.$strict>;
1039
1027
  }, z.core.$strict>;
1028
+ declare const tellWaitObservationSchema: z.ZodUnion<readonly [z.ZodObject<{
1029
+ reason: z.ZodLiteral<"answered">;
1030
+ answer: z.ZodUnknown;
1031
+ }, z.core.$strict>, z.ZodObject<{
1032
+ reason: z.ZodLiteral<"failed">;
1033
+ diagnostic: z.ZodString;
1034
+ }, z.core.$strict>, z.ZodObject<{
1035
+ reason: z.ZodLiteral<"invalid-output">;
1036
+ diagnostic: z.ZodString;
1037
+ answer: z.ZodString;
1038
+ }, z.core.$strict>, z.ZodObject<{
1039
+ reason: z.ZodLiteral<"unanswered">;
1040
+ }, z.core.$strict>, z.ZodObject<{
1041
+ reason: z.ZodLiteral<"deadline">;
1042
+ }, z.core.$strict>]>;
1040
1043
  declare const akumaTellWaitResultSchema: z.ZodObject<{
1041
1044
  akuma: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
1042
1045
  tell: z.ZodObject<{
@@ -1131,11 +1134,16 @@ declare const akumaTellWaitResultSchema: z.ZodObject<{
1131
1134
  }, z.core.$strict>, z.ZodObject<{
1132
1135
  reason: z.ZodLiteral<"failed">;
1133
1136
  diagnostic: z.ZodString;
1137
+ }, z.core.$strict>, z.ZodObject<{
1138
+ reason: z.ZodLiteral<"invalid-output">;
1139
+ diagnostic: z.ZodString;
1140
+ answer: z.ZodString;
1134
1141
  }, z.core.$strict>, z.ZodObject<{
1135
1142
  reason: z.ZodLiteral<"unanswered">;
1136
1143
  }, z.core.$strict>, z.ZodObject<{
1137
1144
  reason: z.ZodLiteral<"deadline">;
1138
1145
  }, z.core.$strict>]>;
1146
+ completedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1139
1147
  }, z.core.$strict>;
1140
1148
  export type AkumaObservation = z.infer<typeof akumaObservationSchema>;
1141
1149
  export type AkumaObservationStage = (Readonly<{
@@ -1148,6 +1156,7 @@ export type AkumaUnobserved = z.infer<typeof akumaUnobservedSchema>;
1148
1156
  export type AkumaWaitResult = z.infer<typeof akumaWaitResultSchema>;
1149
1157
  export type AkumaKillResult = z.infer<typeof akumaKillResultSchema>;
1150
1158
  export type AkumaTellResult = z.infer<typeof akumaTellResultSchema>;
1159
+ export type AkumaTellWaitObservation = z.infer<typeof tellWaitObservationSchema>;
1151
1160
  export type AkumaTellWaitResult = z.infer<typeof akumaTellWaitResultSchema>;
1152
1161
  export declare function parseAkumaObservation(value: unknown): AkumaObservation;
1153
1162
  export declare function isWaitResult(value: unknown): value is AkumaWaitResult;
@@ -1194,12 +1203,6 @@ export declare const fleetResultSchemas: {
1194
1203
  "contract.deliver": "contract.deliver";
1195
1204
  "contract.review": "contract.review";
1196
1205
  }>>, z.ZodTransform<import("./allowed.js").AllowedActions, ("task.add" | "task.addDocument" | "task.compose" | "task.done" | "task.drop" | "task.hold" | "task.resume" | "task.start" | "task.stop" | "task.update" | "akuma.call" | "akuma.kill" | "akuma.tell" | "contract.audit" | "contract.deliver" | "contract.review")[]>>;
1197
- readonly: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
1198
- enforcement: z.ZodLiteral<"native">;
1199
- }, z.core.$strict>, z.ZodObject<{
1200
- enforcement: z.ZodLiteral<"none">;
1201
- diagnostic: z.ZodString;
1202
- }, z.core.$strict>]>>;
1203
1206
  timeline: z.ZodUnion<readonly [z.ZodObject<{
1204
1207
  reportedChanges: z.ZodReadonly<z.ZodArray<z.ZodObject<{
1205
1208
  sequence: z.ZodNumber;
@@ -1811,11 +1814,16 @@ export declare const fleetResultSchemas: {
1811
1814
  }, z.core.$strict>, z.ZodObject<{
1812
1815
  reason: z.ZodLiteral<"failed">;
1813
1816
  diagnostic: z.ZodString;
1817
+ }, z.core.$strict>, z.ZodObject<{
1818
+ reason: z.ZodLiteral<"invalid-output">;
1819
+ diagnostic: z.ZodString;
1820
+ answer: z.ZodString;
1814
1821
  }, z.core.$strict>, z.ZodObject<{
1815
1822
  reason: z.ZodLiteral<"unanswered">;
1816
1823
  }, z.core.$strict>, z.ZodObject<{
1817
1824
  reason: z.ZodLiteral<"deadline">;
1818
1825
  }, z.core.$strict>]>;
1826
+ completedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1819
1827
  }, z.core.$strict>;
1820
1828
  kill: z.ZodObject<{
1821
1829
  results: z.ZodArray<z.ZodObject<{
@@ -61,11 +61,17 @@ const akumaTellResultSchema = z.object({ akuma: akumaIdSchema, tell: tellResultS
61
61
  const tellWaitObservationSchema = z.union([
62
62
  z.object({ reason: z.literal("answered"), answer: z.unknown() }).strict(),
63
63
  z.object({ reason: z.literal("failed"), diagnostic: z.string() }).strict(),
64
+ z.object({ reason: z.literal("invalid-output"), diagnostic: z.string(), answer: z.string() }).strict(),
64
65
  z.object({ reason: z.literal("unanswered") }).strict(),
65
66
  z.object({ reason: z.literal("deadline") }).strict(),
66
67
  ]);
67
68
  const akumaTellWaitResultSchema = z
68
- .object({ akuma: akumaIdSchema, tell: tellResultSchema, observation: tellWaitObservationSchema })
69
+ .object({
70
+ akuma: akumaIdSchema,
71
+ tell: tellResultSchema,
72
+ observation: tellWaitObservationSchema,
73
+ completedAt: z.string().datetime({ offset: true }).nullable().optional(),
74
+ })
69
75
  .strict();
70
76
  export function parseAkumaObservation(value) {
71
77
  return akumaObservationSchema.parse(value);
@@ -1,6 +1,6 @@
1
1
  import type { AkuId } from "../identity.js";
2
2
  import type { ResumeCoordinate } from "../coordinate.js";
3
- import type { ProviderExecution, ProviderOptions, ReadonlyRestraint } from "../provider-recipe.js";
3
+ import type { ProviderExecution, ProviderOptions } from "../provider-recipe.js";
4
4
  import type { AllowedActions } from "../allowed.js";
5
5
  export type { ResumeCoordinate } from "../coordinate.js";
6
6
  export declare class HeartAuthorityCorruptionError extends Error {
@@ -23,13 +23,12 @@ export type Soul = Readonly<{
23
23
  description?: string;
24
24
  provider: ProviderExecution;
25
25
  options: ProviderOptions;
26
- readonly?: ReadonlyRestraint;
27
26
  cwd: string;
28
27
  origin: AkumaOrigin;
29
28
  allowed: AllowedActions;
30
29
  createdAt: string;
31
30
  }>;
32
- export type RequestRecipe = Pick<Soul, "description" | "provider" | "options" | "readonly" | "allowed">;
31
+ export type RequestRecipe = Pick<Soul, "description" | "provider" | "options" | "allowed">;
33
32
  export type BodyEnd = "exited" | "broke-off" | "put-down";
34
33
  export type BodyFact = Readonly<{
35
34
  sequence: number;
@@ -1,5 +1,5 @@
1
1
  import { parseAkuId } from "../identity.js";
2
- import { decodeProviderOptions, decodeProviderRecipe, decodeReadonlyRestraint } from "../provider-recipe.js";
2
+ import { decodeProviderOptions, decodeProviderRecipe } from "../provider-recipe.js";
3
3
  import { historicalAllowedActions } from "../allowed.js";
4
4
  function record(value) {
5
5
  return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -55,17 +55,12 @@ function validateSoul(value) {
55
55
  const description = soul.description === undefined ? undefined : nonblank(soul.description, "description");
56
56
  const provider = decodeProviderRecipe(soul.provider);
57
57
  const options = decodeProviderOptions(soul.options);
58
- const restraint = soul.readonly === undefined ? undefined : decodeReadonlyRestraint(soul.readonly);
59
- if ((options.readonly === true) !== (restraint !== undefined)) {
60
- throw new Error("Akuma soul readonly option and restraint must agree");
61
- }
62
58
  return {
63
59
  id,
64
60
  archetype,
65
61
  ...(description === undefined ? {} : { description }),
66
62
  provider,
67
63
  options,
68
- ...(restraint === undefined ? {} : { readonly: restraint }),
69
64
  cwd: nonblank(soul.cwd, "cwd"),
70
65
  origin: decodeOrigin(soul.origin),
71
66
  allowed: historicalAllowedActions(soul.allowed),
@@ -105,8 +105,7 @@ function isActiveTool(row) {
105
105
  return row.kind === "tool" && row.state === "active";
106
106
  }
107
107
  function isProtectedCurrentTurnActivity(row) {
108
- return (row.kind === "said" ||
109
- (row.kind === "tool" && row.call.kind === "fileChange" && row.state !== "active" && row.state !== "unsettled"));
108
+ return row.kind === "said";
110
109
  }
111
110
  function isSettledTellDeliveredTo(row, turnSequence) {
112
111
  return (row.kind === "tell" &&
@@ -2,19 +2,10 @@ export type SystemPromptMode = "append" | "replace";
2
2
  export type ProviderOptions = Readonly<{
3
3
  model?: string;
4
4
  effort?: string;
5
- readonly?: true;
6
5
  network?: "disabled" | "enabled";
7
- sandbox?: "full-access";
8
6
  systemPrompt?: string;
9
7
  systemPromptMode?: SystemPromptMode;
10
8
  }>;
11
- export type ReadonlyRestraint = Readonly<{
12
- enforcement: "native";
13
- diagnostic?: never;
14
- } | {
15
- enforcement: "none";
16
- diagnostic: string;
17
- }>;
18
9
  export type ProviderExecution = Readonly<{
19
10
  name: string;
20
11
  kind: "acp" | "claude-agent-sdk" | "codex-app-server" | "grok-build" | "opencode-sdk" | "pi";
@@ -23,5 +14,4 @@ export type ProviderExecution = Readonly<{
23
14
  env?: Readonly<Record<string, string>>;
24
15
  }>;
25
16
  export declare function decodeProviderOptions(value: unknown): ProviderOptions;
26
- export declare function decodeReadonlyRestraint(value: unknown): ReadonlyRestraint;
27
17
  export declare function decodeProviderRecipe(input: unknown): ProviderExecution;
@@ -26,17 +26,10 @@ export function decodeProviderOptions(value) {
26
26
  throw new TypeError("provider options must be an object");
27
27
  const model = optionText(options, "model", "refuse");
28
28
  const effort = optionText(options, "effort", "refuse");
29
- if (options.readonly !== undefined && options.readonly !== true) {
30
- throw new TypeError("provider option readonly must be true");
31
- }
32
29
  const network = options.network;
33
30
  if (network !== undefined && network !== "disabled" && network !== "enabled") {
34
31
  throw new TypeError("provider option network must be disabled, enabled");
35
32
  }
36
- const sandbox = options.sandbox;
37
- if (sandbox !== undefined && sandbox !== "full-access") {
38
- throw new TypeError("provider option sandbox must be full-access");
39
- }
40
33
  const systemPrompt = optionText(options, "systemPrompt", "allow");
41
34
  const systemPromptMode = options.systemPromptMode;
42
35
  if (systemPromptMode !== undefined) {
@@ -50,27 +43,11 @@ export function decodeProviderOptions(value) {
50
43
  return Object.freeze({
51
44
  ...(model === undefined ? {} : { model }),
52
45
  ...(effort === undefined ? {} : { effort }),
53
- ...(options.readonly === undefined ? {} : { readonly: true }),
54
46
  ...(network === undefined ? {} : { network }),
55
- ...(sandbox === undefined ? {} : { sandbox }),
56
47
  ...(systemPrompt === undefined ? {} : { systemPrompt }),
57
48
  ...(systemPromptMode === undefined ? {} : { systemPromptMode }),
58
49
  });
59
50
  }
60
- export function decodeReadonlyRestraint(value) {
61
- const restraint = record(value);
62
- if (restraint === null)
63
- throw new TypeError("readonly restraint must be an object");
64
- if (restraint.enforcement === "native") {
65
- return Object.freeze({ enforcement: "native" });
66
- }
67
- if (restraint.enforcement === "none" &&
68
- typeof restraint.diagnostic === "string" &&
69
- restraint.diagnostic.trim().length > 0) {
70
- return Object.freeze({ enforcement: "none", diagnostic: restraint.diagnostic });
71
- }
72
- throw new TypeError("readonly restraint must be native or none with a diagnostic");
73
- }
74
51
  function providerKind(value) {
75
52
  return (value === "acp" ||
76
53
  value === "claude-agent-sdk" ||
@@ -1,5 +1,5 @@
1
1
  import { decodeResumeCoordinate, encodeResumeCoordinate, type ResumeCoordinate } from "./coordinate.js";
2
- import type { ProviderOptions, ReadonlyRestraint } from "./provider-recipe.js";
2
+ import type { ProviderOptions } from "./provider-recipe.js";
3
3
  export type { ResumeCoordinate } from "./coordinate.js";
4
4
  export { AKUMA_REQUESTS_ENV } from "./providers/execution-environment.js";
5
5
  export declare const AGENT_EVENT_TEXT_LIMIT = 16384;
@@ -191,7 +191,6 @@ export type DriveInput = Readonly<{
191
191
  export type ProviderOptionAdmission = Readonly<{
192
192
  kind: "admitted";
193
193
  options: ProviderOptions;
194
- readonly?: ReadonlyRestraint;
195
194
  }> | Readonly<{
196
195
  kind: "refused";
197
196
  diagnostic: string;
@@ -3,9 +3,6 @@ import { decodeAcpConfig } from "./config.js";
3
3
  import { startAcpSession } from "./core.js";
4
4
  export { decodeAcpConfig } from "./config.js";
5
5
  function optionAdmission(options, config) {
6
- if (options.sandbox !== undefined) {
7
- return { kind: "refused", diagnostic: "ACP provider does not support the sandbox option" };
8
- }
9
6
  if (options.network !== undefined) {
10
7
  return { kind: "refused", diagnostic: "ACP provider does not support the network option" };
11
8
  }
@@ -29,14 +26,6 @@ function optionAdmission(options, config) {
29
26
  return {
30
27
  kind: "admitted",
31
28
  options,
32
- ...(options.readonly === undefined
33
- ? {}
34
- : {
35
- readonly: {
36
- enforcement: "none",
37
- diagnostic: "ACP cannot remove task-surface mutation capabilities",
38
- },
39
- }),
40
29
  };
41
30
  }
42
31
  function argv(execution, config, options) {