@astrosheep/keiyaku 4.6.4 → 4.6.6
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/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +43 -8
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +7 -8
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -3
- package/build/src/akuma/akuma-observe.d.ts +18 -15
- package/build/src/akuma/akuma-observe.js +75 -16
- package/build/src/akuma/akuma-wait.d.ts +4 -3
- package/build/src/akuma/akuma-wait.js +75 -53
- package/build/src/akuma/akuma.d.ts +6 -4
- package/build/src/akuma/akuma.js +4 -0
- package/build/src/akuma/call-initial-tell.d.ts +2 -2
- package/build/src/akuma/call-initial-tell.js +1 -1
- package/build/src/akuma/call-request.d.ts +2 -2
- package/build/src/akuma/heart/index.d.ts +7 -2
- package/build/src/akuma/heart/index.js +50 -5
- package/build/src/akuma/heart/tells.d.ts +33 -2
- package/build/src/akuma/heart/tells.js +24 -18
- package/build/src/akuma/heart/timeline.d.ts +23 -1
- package/build/src/akuma/heart/timeline.js +28 -21
- package/build/src/akuma/projection.d.ts +10 -10
- package/build/src/akuma/providers/pi/index.js +72 -39
- package/build/src/akuma/selection-observation.d.ts +20 -20
- package/build/src/akuma-body.js +1 -0
- package/build/src/alias/index.d.ts +0 -1
- package/build/src/alias/index.js +0 -4
- package/build/src/body/amend.d.ts +0 -4
- package/build/src/body/amend.js +0 -3
- package/build/src/body/region.d.ts +0 -1
- package/build/src/body/region.js +0 -3
- package/build/src/body/verification.d.ts +0 -1
- package/build/src/cli/commands/akuma-grammar.js +23 -66
- package/build/src/cli/commands/akuma.js +17 -30
- package/build/src/cli/commands/contract-grammar.d.ts +14 -1
- package/build/src/cli/commands/contract-grammar.js +54 -21
- package/build/src/cli/commands/contract-help.d.ts +9 -8
- package/build/src/cli/commands/contract-help.js +14 -7
- package/build/src/cli/commands/contract.js +57 -117
- package/build/src/cli/commands/install.d.ts +5 -5
- package/build/src/cli/commands/install.js +1 -4
- package/build/src/cli/commands/task-grammar.js +10 -66
- package/build/src/cli/commands/task.d.ts +0 -1
- package/build/src/cli/commands/task.js +34 -53
- package/build/src/cli/coordinates.d.ts +1 -2
- package/build/src/cli/coordinates.js +1 -4
- package/build/src/cli/parse.d.ts +2 -3
- package/build/src/cli/parse.js +24 -66
- package/build/src/cli/render/akuma.d.ts +3 -16
- package/build/src/cli/render/akuma.js +1 -13
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/contract.js +34 -32
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -2
- package/build/src/cli/render/kanshi-akuma.js +14 -7
- package/build/src/cli/render/kanshi.d.ts +3 -1
- package/build/src/cli/render/kanshi.js +44 -32
- package/build/src/cli/render/receipt.js +6 -1
- package/build/src/cli/render/task.d.ts +1 -1
- package/build/src/cli/render/task.js +3 -27
- package/build/src/cli/render/terminal.d.ts +6 -2
- package/build/src/cli/render/terminal.js +8 -2
- package/build/src/cli/runtime.js +3 -16
- package/build/src/cli/scan.d.ts +26 -0
- package/build/src/cli/scan.js +82 -0
- package/build/src/cli/streams.d.ts +5 -0
- package/build/src/cli/streams.js +11 -0
- package/build/src/contract-worktree.js +38 -21
- package/build/src/core/facts/codec.d.ts +1 -2
- package/build/src/core/facts/codec.js +5 -11
- package/build/src/core/facts/types.d.ts +16 -2
- package/build/src/core/facts/types.js +15 -0
- package/build/src/core/verbs/abandon.js +3 -9
- package/build/src/core/verbs/amend.js +2 -9
- package/build/src/core/verbs/arc.js +6 -13
- package/build/src/core/verbs/attestation.js +2 -9
- package/build/src/core/verbs/bind.js +2 -9
- package/build/src/core/verbs/deliver.js +2 -9
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +2 -9
- package/build/src/core/verbs/reintegrate.d.ts +1 -1
- package/build/src/core/verbs/reintegrate.js +2 -9
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +33 -11
- package/build/src/git/hooks.d.ts +2 -4
- package/build/src/git/hooks.js +0 -12
- package/build/src/git/integration.d.ts +5 -3
- package/build/src/git/integration.js +36 -25
- package/build/src/git/nuke.js +4 -4
- package/build/src/git/observe.d.ts +4 -4
- package/build/src/git/observe.js +5 -5
- package/build/src/git/process.d.ts +1 -4
- package/build/src/git/process.js +1 -11
- package/build/src/git/read-observation.js +1 -1
- package/build/src/git/reconcile.d.ts +1 -1
- package/build/src/git/reconcile.js +15 -13
- package/build/src/git/repository.d.ts +2 -6
- package/build/src/git/repository.js +18 -31
- package/build/src/git/scratch.d.ts +6 -6
- package/build/src/git/scratch.js +110 -46
- package/build/src/git/target-placement.d.ts +5 -5
- package/build/src/git/target-placement.js +18 -33
- package/build/src/git/tender.d.ts +6 -2
- package/build/src/git/tender.js +19 -12
- package/build/src/git/terminal-reconcile.js +24 -13
- package/build/src/git/terminal-seal.d.ts +2 -5
- package/build/src/git/terminal-seal.js +5 -3
- package/build/src/git/workspace.d.ts +17 -13
- package/build/src/git/workspace.js +58 -41
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +8 -1
- package/build/src/kanshi/read.js +72 -7
- package/build/src/kanshi/report.d.ts +12 -0
- package/build/src/library/akuma-creation.d.ts +4 -4
- package/build/src/library/bind.d.ts +1 -63
- package/build/src/library/bind.js +3 -9
- package/build/src/library/contract-creation.js +2 -30
- package/build/src/library/contract-execution.d.ts +0 -1
- package/build/src/library/contract-execution.js +9 -34
- package/build/src/library/contract-operations.d.ts +5 -1
- package/build/src/library/contract-operations.js +7 -3
- package/build/src/library/contract-types.d.ts +1 -1
- package/build/src/library/delivery.d.ts +91 -93
- package/build/src/library/delivery.js +2 -1
- package/build/src/library/input.d.ts +0 -2
- package/build/src/library/input.js +0 -4
- package/build/src/library/invocation.d.ts +0 -1
- package/build/src/library/invocation.js +3 -25
- package/build/src/library/outcome.d.ts +651 -602
- package/build/src/library/outcome.js +4 -4
- package/build/src/library/reconcile.d.ts +6 -0
- package/build/src/library/reconcile.js +31 -1
- package/build/src/library/repo.d.ts +0 -1
- package/build/src/library/selection.d.ts +1 -10
- package/build/src/library/selection.js +14 -15
- package/build/src/protocol/abandon.d.ts +1 -1
- package/build/src/protocol/abandon.js +3 -10
- package/build/src/protocol/amend.js +2 -5
- package/build/src/protocol/arc.d.ts +1 -1
- package/build/src/protocol/arc.js +2 -9
- package/build/src/protocol/attempt.d.ts +3 -20
- package/build/src/protocol/attempt.js +6 -5
- package/build/src/protocol/audit.d.ts +1 -0
- package/build/src/protocol/audit.js +10 -11
- package/build/src/protocol/completion.d.ts +129 -55
- package/build/src/protocol/completion.js +62 -73
- package/build/src/protocol/deliver.d.ts +7 -5
- package/build/src/protocol/deliver.js +74 -44
- package/build/src/protocol/execution-observation.d.ts +2 -4
- package/build/src/protocol/execution-observation.js +3 -7
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -0
- package/build/src/protocol/operations.d.ts +24 -12
- package/build/src/protocol/operations.js +36 -15
- package/build/src/protocol/placement.d.ts +2 -1
- package/build/src/protocol/placement.js +21 -5
- package/build/src/protocol/progress.d.ts +1 -1
- package/build/src/protocol/read/status.js +58 -41
- package/build/src/protocol/reintegrate.d.ts +1 -1
- package/build/src/protocol/reintegrate.js +10 -19
- package/build/src/protocol/review.d.ts +3 -28
- package/build/src/protocol/review.js +10 -37
- package/build/src/protocol/run.d.ts +19 -7
- package/build/src/protocol/run.js +19 -9
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -4
- package/build/src/settlement/holder.js +3 -6
- package/build/src/task/board.d.ts +6 -0
- package/build/src/task/board.js +30 -1
- package/build/src/task/catalog.js +1 -4
- package/build/src/task/compose.d.ts +0 -1
- package/build/src/task/compose.js +0 -1
- package/build/src/task/context.d.ts +0 -1
- package/build/src/task/context.js +0 -3
- package/build/src/task/created-observation.d.ts +5 -1
- package/build/src/task/created-observation.js +12 -5
- package/build/src/task/index.d.ts +1 -1
- package/build/src/task/index.js +7 -6
- package/build/src/task/input.d.ts +0 -6
- package/build/src/task/input.js +2 -14
- package/build/src/task/mutation.d.ts +3 -4
- package/build/src/task/mutation.js +11 -39
- package/build/src/task/operations.d.ts +2 -7
- package/build/src/task/operations.js +37 -49
- package/build/src/task/query.d.ts +0 -1
- package/build/src/task/query.js +1 -4
- package/build/src/task/store.d.ts +0 -2
- package/build/src/task/store.js +27 -11
- package/build/src/verification/declaration.js +3 -2
- package/build/src/verification/execution.d.ts +3 -2
- package/build/src/verification/execution.js +10 -6
- package/build/src/workspace-place.d.ts +0 -1
- package/build/src/workspace-place.js +0 -11
- package/package.json +7 -3
|
@@ -16,6 +16,12 @@ shorter, world-local name.
|
|
|
16
16
|
|
|
17
17
|
## Call a new Akuma
|
|
18
18
|
|
|
19
|
+
```bash
|
|
20
|
+
keiyaku call worker "Summarize the recent changes in src/cli"
|
|
21
|
+
keiyaku call worker --alias @reviewer --wait 10m - < brief.md
|
|
22
|
+
keiyaku call worker
|
|
23
|
+
```
|
|
24
|
+
|
|
19
25
|
The prompt is optional for prompt-free birth. Otherwise it is the new Akuma's
|
|
20
26
|
first prompt: give it as one argument, or use `-` to read stdin, never both.
|
|
21
27
|
Calls are detached by default: they return the new identity after birth without
|
|
@@ -34,34 +40,57 @@ capabilities, not merely for parallelism.
|
|
|
34
40
|
`--contract` only records the association. It does not tell the Akuma the
|
|
35
41
|
Contract or worktree. Put them in the prompt explicitly:
|
|
36
42
|
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
```bash
|
|
44
|
+
keiyaku call worker --contract kei/add-rate-limit-a1b2 --workdir /path/to/worktree - <<'EOF'
|
|
45
|
+
Contract: kei/add-rate-limit-a1b2
|
|
46
|
+
Worktree: /path/to/worktree
|
|
47
|
+
This Arc: implement the limiter and its tests
|
|
48
|
+
EOF
|
|
41
49
|
```
|
|
42
50
|
|
|
43
51
|
`--contract` does not choose a worktree. Use `--workdir <path>` when needed.
|
|
44
52
|
|
|
45
53
|
## Tell or ask an existing Akuma
|
|
46
54
|
|
|
55
|
+
```bash
|
|
56
|
+
keiyaku tell @reviewer "The candidate moved; re-examine the worktree"
|
|
57
|
+
keiyaku tell @reviewer --interrupt - < new-priority.md
|
|
58
|
+
keiyaku ask @reviewer --wait 10m "What is your verdict?"
|
|
59
|
+
keiyaku ask @reviewer --schema verdict.schema.json - < question.md
|
|
60
|
+
```
|
|
61
|
+
|
|
47
62
|
`tell` admits the next instruction and returns its admission receipt; it does
|
|
48
63
|
not await an answer. `ask` admits a Tell and observes that exact answer,
|
|
49
64
|
unbounded unless `--wait` limits observation. Both require a prompt and accept
|
|
50
65
|
`--interrupt` to put down current work before admitting the new Tell. Schema
|
|
51
66
|
belongs only to `ask`; `tell --schema` and `tell --wait` refuse and point to
|
|
52
67
|
`ask`. A deadline never withdraws an admitted Tell. Read `tell --help` and
|
|
53
|
-
`ask --help` for
|
|
68
|
+
`ask --help` for the complete flag grammar.
|
|
54
69
|
|
|
55
70
|
## Observe work
|
|
56
71
|
|
|
72
|
+
```bash
|
|
73
|
+
keiyaku wait @deliverer @reviewer
|
|
74
|
+
keiyaku wait --all --timeout 30m @deliverer @reviewer
|
|
75
|
+
```
|
|
76
|
+
|
|
57
77
|
Use `wait` for one or more existing Akumas. The default is `--any`; use
|
|
58
78
|
`--all` for every selected Akuma. `--timeout` limits observation and does not
|
|
59
79
|
stop workers. A completed Akuma already counts, so repeating a wait can return
|
|
60
|
-
immediately. See `wait --help` for
|
|
61
|
-
existing Akuma-wide work, not the answer to a newly admitted Tell.
|
|
80
|
+
immediately. See `wait --help` for the complete grammar. Unlike `ask`, `wait`
|
|
81
|
+
observes existing Akuma-wide work, not the answer to a newly admitted Tell.
|
|
62
82
|
|
|
63
83
|
## Inspect and retrieve results
|
|
64
84
|
|
|
85
|
+
```bash
|
|
86
|
+
keiyaku status
|
|
87
|
+
keiyaku status @reviewer
|
|
88
|
+
keiyaku ls aku/
|
|
89
|
+
keiyaku ls "aku/*/*"
|
|
90
|
+
keiyaku history @reviewer --last
|
|
91
|
+
keiyaku history @reviewer --id turn/3
|
|
92
|
+
```
|
|
93
|
+
|
|
65
94
|
`status` shows the roster or one Akuma's workdir and effective actions.
|
|
66
95
|
`ls aku/` shows callable names; `ls "aku/*/*"` shows born workers.
|
|
67
96
|
`history --last` reads the latest complete answer; `history --id` reads an
|
|
@@ -70,10 +99,16 @@ move; see `history --help` for paging.
|
|
|
70
99
|
|
|
71
100
|
## Stop and branch
|
|
72
101
|
|
|
102
|
+
```bash
|
|
103
|
+
keiyaku kill @reviewer
|
|
104
|
+
keiyaku fork @reviewer --at turn/3
|
|
105
|
+
```
|
|
106
|
+
|
|
73
107
|
`kill` stops current work without admitting a Tell, deleting the Akuma, or
|
|
74
108
|
removing its history. `fork` creates a new Akuma from one exact retained
|
|
75
109
|
answered history point; the source is unchanged, and providers that cannot
|
|
76
|
-
fork report that refusal. See
|
|
110
|
+
fork report that refusal. See `kill --help` and `fork --help` for the
|
|
111
|
+
complete grammar.
|
|
77
112
|
|
|
78
113
|
## JavaScript automation
|
|
79
114
|
|
|
@@ -154,14 +154,13 @@ fence containing commands runnable as written. Use separate fences when checks
|
|
|
154
154
|
need different timeouts or results. Use an explicit timeout for bounded
|
|
155
155
|
commands; `5m` is the normal baseline.
|
|
156
156
|
|
|
157
|
-
Verification runs
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
evidence
|
|
164
|
-
checked at placement.
|
|
157
|
+
Verification runs only when the Contract selects the `verified` gate, against
|
|
158
|
+
the exact integration snapshot in a clean disposable worktree for that attempt.
|
|
159
|
+
`deliver` reuses current satisfied evidence or runs the declarations; unsatisfied
|
|
160
|
+
results and runtime stops prevent placement. `audit` runs declarations for a
|
|
161
|
+
prospective candidate. Without `verified`, no verb runs Verification and the
|
|
162
|
+
section is inert document text. `reviewed` independently requires review
|
|
163
|
+
evidence. Selected gates are checked at placement.
|
|
165
164
|
|
|
166
165
|
For an existing Task with real scheduling or dependency value:
|
|
167
166
|
|
|
@@ -72,9 +72,9 @@ Each act changes a different part of the world:
|
|
|
72
72
|
audit; when it matters, merge the target branch (main when selected) in the
|
|
73
73
|
worktree and resolve conflicts there before auditing.
|
|
74
74
|
- **Audit:** Previews the candidate and target without tendering or claiming.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
no new verdict.
|
|
75
|
+
With `verified` selected, Verification runs for the captured subject and can
|
|
76
|
+
record an attestation. Without that gate, the section is inert text and no
|
|
77
|
+
verb runs Verification. A stopped run records no new verdict.
|
|
78
78
|
- **Deliver:** Captures a tender and integration against the observed target;
|
|
79
79
|
journal gains a delivered candidate. Ready prerequisites and gates trigger
|
|
80
80
|
placement and claim in this invocation; otherwise the candidate waits.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AkuId, type AkumaPaths } from "./identity.js";
|
|
2
|
-
import { selectHistory, type ActivityHistory, type ActivityRow, type ActivitySnapshot } from "./projection.js";
|
|
2
|
+
import { selectHistory, selectSnapshot, type ActivityHistory, type ActivityRow, type ActivitySnapshot, type TurnLedger } from "./projection.js";
|
|
3
3
|
import type { WorldRoot } from "../world.js";
|
|
4
4
|
import type { AkumaAlias } from "../identity/selector.js";
|
|
5
5
|
import type { AkumaListRow, AkumaStatus, UnbornAkumaListRow } from "./akuma.js";
|
|
@@ -16,24 +16,27 @@ type BudgetedStatusObservation = Readonly<{
|
|
|
16
16
|
export type LiveStatusObservation = BudgetedStatusObservation & Readonly<{
|
|
17
17
|
rows: readonly ActivityRow[];
|
|
18
18
|
}>;
|
|
19
|
-
|
|
20
|
-
export declare function bornLiveStatus(paths: AkumaPaths, expected: AkuId, input: Readonly<{
|
|
21
|
-
aperture: "monitoring" | "receipt";
|
|
22
|
-
ordinaryBudget?: number;
|
|
23
|
-
admittedTellId?: string;
|
|
24
|
-
}>): Promise<LiveStatusObservation>;
|
|
25
|
-
export declare function bornStatus(paths: AkumaPaths, expected: AkuId, input: Readonly<{
|
|
26
|
-
aperture: "monitoring" | "receipt";
|
|
27
|
-
ordinaryBudget?: number;
|
|
28
|
-
admittedTellId?: string;
|
|
29
|
-
}>): Promise<BudgetedStatusObservation>;
|
|
30
|
-
export declare function readLiveStatus(worldPath: WorldRoot, id: AkuId, input: Readonly<{
|
|
19
|
+
type StatusObservationInput = Readonly<{
|
|
31
20
|
aperture: "monitoring" | "receipt";
|
|
32
21
|
ordinaryBudget?: number;
|
|
33
22
|
admittedTellId?: string;
|
|
34
|
-
}
|
|
23
|
+
}>;
|
|
24
|
+
type StatusProjection = Readonly<{
|
|
25
|
+
ledger: TurnLedger;
|
|
26
|
+
selected: ReturnType<typeof selectSnapshot>;
|
|
27
|
+
}>;
|
|
28
|
+
/** Private to a live wait: retain only this member's current frontier and last selection. */
|
|
29
|
+
export declare function createLiveStatusReader(paths: AkumaPaths, expected: AkuId): {
|
|
30
|
+
clear: () => void;
|
|
31
|
+
read(input: StatusObservationInput, signal?: AbortSignal): Promise<LiveStatusObservation>;
|
|
32
|
+
};
|
|
33
|
+
/** Internal live companion for an observation loop; it is not a public result. */
|
|
34
|
+
export declare function bornLiveStatus(paths: AkumaPaths, expected: AkuId, input: StatusObservationInput, signal?: AbortSignal, readProjection?: () => Promise<StatusProjection>): Promise<LiveStatusObservation>;
|
|
35
|
+
export declare function bornStatus(paths: AkumaPaths, expected: AkuId, input: StatusObservationInput): Promise<BudgetedStatusObservation>;
|
|
36
|
+
export declare function readLiveStatus(worldPath: WorldRoot, id: AkuId, input: StatusObservationInput, signal?: AbortSignal): Promise<LiveStatusObservation>;
|
|
35
37
|
export declare function defaultWaitComplete(status: AkumaStatus): boolean;
|
|
36
|
-
|
|
38
|
+
/** Probe completion only; returned statuses still come from a full observation. */
|
|
39
|
+
export declare function readWaitComplete(worldPath: WorldRoot, ids: readonly AkuId[], completion: "any" | "all", signal?: AbortSignal): Promise<boolean>;
|
|
37
40
|
export type WaitReason = "completed" | "deadline";
|
|
38
41
|
/**
|
|
39
42
|
* The one deadline-aware observation loop for public Akuma waiting. It always
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readStatusFacts, readLifeSnapshot, HeldAkumaLeash, isHeartAbsent, life, lifeAt, probeLeash, readHeart, readSeal, readSoul, } from "./heart/index.js";
|
|
1
|
+
import { readStatusFacts, createStatusFactReader, readLifeSnapshot, HeldAkumaLeash, isHeartAbsent, life, lifeAt, probeLeash, readHeart, readSeal, readSoul, } from "./heart/index.js";
|
|
2
2
|
import { pathsForAkuId } from "./identity.js";
|
|
3
3
|
import { ordinarySnapshotBudget, projectTurns, selectHistory, selectSnapshot, } from "./projection.js";
|
|
4
4
|
import { resolveProviderExecution } from "./providers/index.js";
|
|
@@ -59,21 +59,56 @@ async function bornObservation(paths, expected, read, snapshot) {
|
|
|
59
59
|
claim?.release();
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
function snapshotSelection(input) {
|
|
63
|
+
return {
|
|
64
|
+
aperture: input.aperture,
|
|
65
|
+
budget: ordinarySnapshotBudget(input.ordinaryBudget),
|
|
66
|
+
...(input.admittedTellId === undefined ? {} : { admittedTellId: input.admittedTellId }),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Private to a live wait: retain only this member's current frontier and last selection. */
|
|
70
|
+
export function createLiveStatusReader(paths, expected) {
|
|
71
|
+
const reader = createStatusFactReader(paths);
|
|
72
|
+
let memo;
|
|
73
|
+
const clear = () => {
|
|
74
|
+
reader.clear();
|
|
75
|
+
memo = undefined;
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
clear,
|
|
79
|
+
async read(input, signal) {
|
|
80
|
+
try {
|
|
81
|
+
return await bornLiveStatus(paths, expected, input, signal, async () => {
|
|
82
|
+
const facts = await reader.read(input, signal);
|
|
83
|
+
const ledger = memo?.facts === facts ? memo.ledger : projectTurns(facts);
|
|
84
|
+
const options = snapshotSelection(input);
|
|
85
|
+
const selected = memo?.ledger === ledger &&
|
|
86
|
+
memo.options.aperture === options.aperture &&
|
|
87
|
+
memo.options.admittedTellId === options.admittedTellId &&
|
|
88
|
+
memo.options.budget.tail === options.budget.tail &&
|
|
89
|
+
memo.options.budget.voice === options.budget.voice
|
|
90
|
+
? memo.selected
|
|
91
|
+
: selectSnapshot(ledger, options);
|
|
92
|
+
memo = { facts, ledger, options, selected };
|
|
93
|
+
return { ledger, selected };
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
clear();
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
62
103
|
/** Internal live companion for an observation loop; it is not a public result. */
|
|
63
|
-
export async function bornLiveStatus(paths, expected, input) {
|
|
104
|
+
export async function bornLiveStatus(paths, expected, input, signal, readProjection) {
|
|
64
105
|
if (input.ordinaryBudget !== undefined && (!Number.isSafeInteger(input.ordinaryBudget) || input.ordinaryBudget < 0))
|
|
65
106
|
throw new TypeError("ordinary budget must be a nonnegative safe integer");
|
|
66
|
-
const { snapshot, soul, currentLife } = await bornObservation(paths, expected, () => readLifeSnapshot(paths));
|
|
107
|
+
const { snapshot, soul, currentLife } = await bornObservation(paths, expected, () => readLifeSnapshot(paths, signal));
|
|
67
108
|
const resumeUnsupported = currentLife === "stranded" &&
|
|
68
109
|
snapshot.latestSession?.provider === soul.provider.name &&
|
|
69
110
|
(await resolveProviderExecution(soul.provider)).adapter.resume === undefined;
|
|
70
|
-
const
|
|
71
|
-
const ledger = projectTurns(facts);
|
|
72
|
-
const selected = selectSnapshot(ledger, {
|
|
73
|
-
aperture: input.aperture,
|
|
74
|
-
budget: ordinarySnapshotBudget(input.ordinaryBudget),
|
|
75
|
-
...(input.admittedTellId === undefined ? {} : { admittedTellId: input.admittedTellId }),
|
|
76
|
-
});
|
|
111
|
+
const { ledger, selected } = readProjection === undefined ? await readStatusProjection(paths, input, signal) : await readProjection();
|
|
77
112
|
return {
|
|
78
113
|
status: {
|
|
79
114
|
id: soul.id,
|
|
@@ -87,12 +122,20 @@ export async function bornLiveStatus(paths, expected, input) {
|
|
|
87
122
|
rows: ledger.rows,
|
|
88
123
|
};
|
|
89
124
|
}
|
|
125
|
+
async function readStatusProjection(paths, input, signal) {
|
|
126
|
+
const facts = await readStatusFacts(paths, input, signal);
|
|
127
|
+
const ledger = projectTurns(facts);
|
|
128
|
+
return {
|
|
129
|
+
ledger,
|
|
130
|
+
selected: selectSnapshot(ledger, snapshotSelection(input)),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
90
133
|
export async function bornStatus(paths, expected, input) {
|
|
91
134
|
const { rows: _rows, ...status } = await bornLiveStatus(paths, expected, input);
|
|
92
135
|
return status;
|
|
93
136
|
}
|
|
94
|
-
export async function readLiveStatus(worldPath, id, input) {
|
|
95
|
-
return await bornLiveStatus(pathsForAkuId(worldPath, id), id, input);
|
|
137
|
+
export async function readLiveStatus(worldPath, id, input, signal) {
|
|
138
|
+
return await bornLiveStatus(pathsForAkuId(worldPath, id), id, input, signal);
|
|
96
139
|
}
|
|
97
140
|
function complete(life, pending) {
|
|
98
141
|
return life !== "running" && !pending;
|
|
@@ -100,10 +143,26 @@ function complete(life, pending) {
|
|
|
100
143
|
export function defaultWaitComplete(status) {
|
|
101
144
|
return complete(status.life, status.timeline.entries.some((entry) => entry.kind === "row" && entry.row.kind === "tell" && entry.row.state === "pending"));
|
|
102
145
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
146
|
+
/** Probe completion only; returned statuses still come from a full observation. */
|
|
147
|
+
export async function readWaitComplete(worldPath, ids, completion, signal) {
|
|
148
|
+
let completed = 0;
|
|
149
|
+
for (const id of ids) {
|
|
150
|
+
signal?.throwIfAborted();
|
|
151
|
+
try {
|
|
152
|
+
const paths = pathsForAkuId(worldPath, id);
|
|
153
|
+
const observed = await bornObservation(paths, id, () => readLifeSnapshot(paths, signal));
|
|
154
|
+
if (complete(observed.currentLife, observed.snapshot.hasPendingTell)) {
|
|
155
|
+
if (completion === "any")
|
|
156
|
+
return true;
|
|
157
|
+
completed += 1;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
if (ids.length === 1 || error instanceof AkumaNotBornError)
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return ids.length > 0 && completed === ids.length;
|
|
107
166
|
}
|
|
108
167
|
const OBSERVATION_POLL_MS = 100;
|
|
109
168
|
/**
|
|
@@ -53,9 +53,10 @@ export type NativeWaitResult = Readonly<{
|
|
|
53
53
|
* The one lower set-observation owner for Akuma wait completion. It serves the
|
|
54
54
|
* standalone one-ID association-free face and the plural any/all face with one
|
|
55
55
|
* ordered round algorithm, one shared ordinary-detail budget, transient
|
|
56
|
-
* unreadable peers, and an honest final deadline edge.
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* unreadable peers, and an honest final deadline edge. A silent observation —
|
|
57
|
+
* no live row callback and no custom judge — decides which running rounds to
|
|
58
|
+
* skip with the owner's lightweight completion probe over the selected set; a
|
|
59
|
+
* live viewer or a custom judge always observes full rounds.
|
|
59
60
|
*/
|
|
60
61
|
export declare function executeWaitAkuma(input: WaitExecutionInput): Promise<NativeWaitResult>;
|
|
61
62
|
export {};
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { AkumaNotBornError } from "./akuma-errors.js";
|
|
2
|
-
import { defaultWaitComplete, readLiveStatus, readWaitComplete, waitForObservation, } from "./akuma-observe.js";
|
|
2
|
+
import { createLiveStatusReader, defaultWaitComplete, readLiveStatus, readWaitComplete, waitForObservation, } from "./akuma-observe.js";
|
|
3
|
+
import { pathsForAkuId } from "./identity.js";
|
|
3
4
|
const SHARED_ORDINARY_BUDGET = 30;
|
|
4
|
-
async function observeWaitRound(path, ids, signal) {
|
|
5
|
+
async function observeWaitRound(path, ids, signal, readers) {
|
|
6
|
+
const read = async (id, ordinaryBudget) => {
|
|
7
|
+
const options = { aperture: "monitoring", ...(ordinaryBudget === undefined ? {} : { ordinaryBudget }) };
|
|
8
|
+
if (readers === undefined)
|
|
9
|
+
return await readLiveStatus(path, id, options, signal);
|
|
10
|
+
let reader = readers.get(id);
|
|
11
|
+
if (reader === undefined) {
|
|
12
|
+
reader = createLiveStatusReader(pathsForAkuId(path, id), id);
|
|
13
|
+
readers.set(id, reader);
|
|
14
|
+
}
|
|
15
|
+
return await reader.read(options, signal);
|
|
16
|
+
};
|
|
5
17
|
signal?.throwIfAborted();
|
|
6
18
|
if (ids.length <= 1) {
|
|
7
|
-
const observations = await Promise.all(ids.map(async (id) => await
|
|
19
|
+
const observations = await Promise.all(ids.map(async (id) => await read(id)));
|
|
8
20
|
return { observations, unobserved: [] };
|
|
9
21
|
}
|
|
10
22
|
let remaining = SHARED_ORDINARY_BUDGET;
|
|
@@ -13,11 +25,13 @@ async function observeWaitRound(path, ids, signal) {
|
|
|
13
25
|
for (const id of ids) {
|
|
14
26
|
signal?.throwIfAborted();
|
|
15
27
|
try {
|
|
16
|
-
const observed = await
|
|
28
|
+
const observed = await read(id, remaining);
|
|
17
29
|
observations.push(observed);
|
|
18
30
|
remaining -= observed.ordinarySelected;
|
|
19
31
|
}
|
|
20
32
|
catch (error) {
|
|
33
|
+
readers?.get(id)?.clear();
|
|
34
|
+
readers?.delete(id);
|
|
21
35
|
if (error instanceof AkumaNotBornError)
|
|
22
36
|
throw error;
|
|
23
37
|
unobserved.push({ id, diagnostic: diagnostic(error) });
|
|
@@ -54,59 +68,67 @@ function selectionOrderedIds(ids, order) {
|
|
|
54
68
|
* The one lower set-observation owner for Akuma wait completion. It serves the
|
|
55
69
|
* standalone one-ID association-free face and the plural any/all face with one
|
|
56
70
|
* ordered round algorithm, one shared ordinary-detail budget, transient
|
|
57
|
-
* unreadable peers, and an honest final deadline edge.
|
|
58
|
-
*
|
|
59
|
-
*
|
|
71
|
+
* unreadable peers, and an honest final deadline edge. A silent observation —
|
|
72
|
+
* no live row callback and no custom judge — decides which running rounds to
|
|
73
|
+
* skip with the owner's lightweight completion probe over the selected set; a
|
|
74
|
+
* live viewer or a custom judge always observes full rounds.
|
|
60
75
|
*/
|
|
61
76
|
export async function executeWaitAkuma(input) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
input.onSelected(ordered.map((id) => ({ id, ...facts.get(id) })));
|
|
72
|
-
}
|
|
73
|
-
const observeRound = async (round) => {
|
|
74
|
-
if (input.observe === undefined)
|
|
75
|
-
return;
|
|
76
|
-
const observed = [];
|
|
77
|
-
for (const observation of round.observations) {
|
|
78
|
-
input.signal?.throwIfAborted();
|
|
79
|
-
const { status, rows } = observation;
|
|
80
|
-
let known = facts.get(status.id);
|
|
81
|
-
if (known === undefined && input.identity !== undefined) {
|
|
82
|
-
known = await input.identity(status.id);
|
|
83
|
-
facts.set(status.id, known);
|
|
84
|
-
}
|
|
85
|
-
if (known === undefined) {
|
|
86
|
-
observed.push({ status, rows, contract: { kind: "none" } });
|
|
87
|
-
continue;
|
|
77
|
+
const readers = input.observe === undefined ? undefined : new Map();
|
|
78
|
+
try {
|
|
79
|
+
// Identity facts are read once per observed Akuma, not once per 100ms round.
|
|
80
|
+
const facts = new Map();
|
|
81
|
+
if (input.onSelected !== undefined) {
|
|
82
|
+
for (const id of input.ids) {
|
|
83
|
+
input.signal?.throwIfAborted();
|
|
84
|
+
const known = input.identity === undefined ? undefined : await input.identity(id);
|
|
85
|
+
facts.set(id, known ?? { contract: { kind: "none" } });
|
|
88
86
|
}
|
|
89
|
-
|
|
87
|
+
const ordered = input.selectionOrder === undefined ? input.ids : selectionOrderedIds(input.ids, input.selectionOrder);
|
|
88
|
+
input.onSelected(ordered.map((id) => ({ id, ...facts.get(id) })));
|
|
90
89
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
90
|
+
const observeRound = async (round) => {
|
|
91
|
+
if (input.observe === undefined)
|
|
92
|
+
return;
|
|
93
|
+
const observed = [];
|
|
94
|
+
for (const observation of round.observations) {
|
|
95
|
+
input.signal?.throwIfAborted();
|
|
96
|
+
const { status, rows } = observation;
|
|
97
|
+
let known = facts.get(status.id);
|
|
98
|
+
if (known === undefined && input.identity !== undefined) {
|
|
99
|
+
known = await input.identity(status.id);
|
|
100
|
+
facts.set(status.id, known);
|
|
101
|
+
}
|
|
102
|
+
if (known === undefined) {
|
|
103
|
+
observed.push({ status, rows, contract: { kind: "none" } });
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
observed.push({ status, rows, ...known });
|
|
107
|
+
}
|
|
108
|
+
input.observe(structuredClone(observed));
|
|
109
|
+
};
|
|
110
|
+
const waited = await waitForObservation({
|
|
111
|
+
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
112
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
113
|
+
...(input.predicate === undefined && input.observe === undefined
|
|
114
|
+
? { probe: async () => await readWaitComplete(input.path, input.ids, input.completion, input.signal) }
|
|
115
|
+
: {}),
|
|
116
|
+
observe: async () => await observeWaitRound(input.path, input.ids, input.signal, readers),
|
|
117
|
+
complete: (round) => roundComplete(round, input.completion, input.predicate),
|
|
118
|
+
onObserve: async (round) => await observeRound(round),
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
mode: input.completion,
|
|
122
|
+
reason: waited.reason,
|
|
123
|
+
observations: waited.value.observations.map((observation) => observation.status),
|
|
124
|
+
unobserved: waited.value.unobserved,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
for (const reader of readers?.values() ?? [])
|
|
129
|
+
reader.clear();
|
|
130
|
+
readers?.clear();
|
|
131
|
+
}
|
|
110
132
|
}
|
|
111
133
|
function diagnostic(error) {
|
|
112
134
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -156,8 +156,8 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
156
156
|
}>;
|
|
157
157
|
turnSequence: z.ZodNumber;
|
|
158
158
|
receipt: z.ZodOptional<z.ZodEnum<{
|
|
159
|
-
required: "required";
|
|
160
159
|
unavailable: "unavailable";
|
|
160
|
+
required: "required";
|
|
161
161
|
}>>;
|
|
162
162
|
}, z.core.$strict>, z.ZodTransform<Readonly<{
|
|
163
163
|
turnSequence: number;
|
|
@@ -168,7 +168,7 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
168
168
|
deliveredAt: string;
|
|
169
169
|
route: "live" | "launch";
|
|
170
170
|
turnSequence: number;
|
|
171
|
-
receipt?: "
|
|
171
|
+
receipt?: "unavailable" | "required" | undefined;
|
|
172
172
|
}>>>>;
|
|
173
173
|
}, z.core.$strict>]>, z.ZodObject<{
|
|
174
174
|
kind: z.ZodLiteral<"tool">;
|
|
@@ -363,8 +363,8 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
363
363
|
}>;
|
|
364
364
|
turnSequence: z.ZodNumber;
|
|
365
365
|
receipt: z.ZodOptional<z.ZodEnum<{
|
|
366
|
-
required: "required";
|
|
367
366
|
unavailable: "unavailable";
|
|
367
|
+
required: "required";
|
|
368
368
|
}>>;
|
|
369
369
|
}, z.core.$strict>, z.ZodTransform<Readonly<{
|
|
370
370
|
turnSequence: number;
|
|
@@ -375,7 +375,7 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
375
375
|
deliveredAt: string;
|
|
376
376
|
route: "live" | "launch";
|
|
377
377
|
turnSequence: number;
|
|
378
|
-
receipt?: "
|
|
378
|
+
receipt?: "unavailable" | "required" | undefined;
|
|
379
379
|
}>>>>;
|
|
380
380
|
}, z.core.$strict>]>, z.ZodObject<{
|
|
381
381
|
kind: z.ZodLiteral<"tool">;
|
|
@@ -450,6 +450,8 @@ export declare function listAkumaArchetypes(path: WorldRoot, input?: Readonly<{
|
|
|
450
450
|
* observed extent. World Alias context is attached by the upper composition.
|
|
451
451
|
*/
|
|
452
452
|
export declare function readAkumaRoster(path: WorldRoot, input?: AkumaListInput): Promise<AkumaList>;
|
|
453
|
+
/** Internal recent observation with an aperture already validated by the composition. */
|
|
454
|
+
export declare function observeAkumaRoster(path: WorldRoot, limit: number, selected?: string): Promise<AkumaList>;
|
|
453
455
|
/** The complete native roster for callers whose semantics require a frozen set. */
|
|
454
456
|
export declare function readAkumaCompleteRoster(path: WorldRoot, input?: Readonly<{
|
|
455
457
|
archetype?: string;
|
package/build/src/akuma/akuma.js
CHANGED
|
@@ -118,6 +118,10 @@ function rosterArchetype(input, allowLimit) {
|
|
|
118
118
|
export async function readAkumaRoster(path, input = {}) {
|
|
119
119
|
const selected = rosterArchetype(input, true);
|
|
120
120
|
const limit = boundedListLimit(input.limit);
|
|
121
|
+
return observeAkumaRoster(path, limit, selected);
|
|
122
|
+
}
|
|
123
|
+
/** Internal recent observation with an aperture already validated by the composition. */
|
|
124
|
+
export async function observeAkumaRoster(path, limit, selected) {
|
|
121
125
|
const observedAt = new Date().toISOString();
|
|
122
126
|
const known = await knownAkuma(path, selected);
|
|
123
127
|
const candidatesWithBounds = await boundedMap(known.rows, async (row) => ({
|
|
@@ -78,8 +78,8 @@ export declare const tellResultSchema: z.ZodObject<{
|
|
|
78
78
|
}>;
|
|
79
79
|
turnSequence: z.ZodNumber;
|
|
80
80
|
receipt: z.ZodOptional<z.ZodEnum<{
|
|
81
|
-
required: "required";
|
|
82
81
|
unavailable: "unavailable";
|
|
82
|
+
required: "required";
|
|
83
83
|
}>>;
|
|
84
84
|
}, z.core.$strict>, z.ZodTransform<Readonly<{
|
|
85
85
|
turnSequence: number;
|
|
@@ -90,7 +90,7 @@ export declare const tellResultSchema: z.ZodObject<{
|
|
|
90
90
|
deliveredAt: string;
|
|
91
91
|
route: "live" | "launch";
|
|
92
92
|
turnSequence: number;
|
|
93
|
-
receipt?: "
|
|
93
|
+
receipt?: "unavailable" | "required" | undefined;
|
|
94
94
|
}>>>>;
|
|
95
95
|
}, z.core.$strict>;
|
|
96
96
|
wake: z.ZodUnion<readonly [z.ZodObject<{
|
|
@@ -37,7 +37,7 @@ export async function admitCallInitialTell(input) {
|
|
|
37
37
|
const birth = await waitForObservation({
|
|
38
38
|
timeoutMs: BIRTH_TIMEOUT_MS,
|
|
39
39
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
40
|
-
probe: async () => await readWaitComplete(input.world, input.id),
|
|
40
|
+
probe: async () => await readWaitComplete(input.world, [input.id], "all", input.signal),
|
|
41
41
|
observe: async () => (await bornStatus(paths, input.id, { aperture: "receipt" })).status,
|
|
42
42
|
complete: defaultWaitComplete,
|
|
43
43
|
});
|
|
@@ -206,8 +206,8 @@ declare const liveResultSchema: z.ZodObject<{
|
|
|
206
206
|
}>;
|
|
207
207
|
turnSequence: z.ZodNumber;
|
|
208
208
|
receipt: z.ZodOptional<z.ZodEnum<{
|
|
209
|
-
required: "required";
|
|
210
209
|
unavailable: "unavailable";
|
|
210
|
+
required: "required";
|
|
211
211
|
}>>;
|
|
212
212
|
}, z.core.$strict>, z.ZodTransform<Readonly<{
|
|
213
213
|
turnSequence: number;
|
|
@@ -218,7 +218,7 @@ declare const liveResultSchema: z.ZodObject<{
|
|
|
218
218
|
deliveredAt: string;
|
|
219
219
|
route: "live" | "launch";
|
|
220
220
|
turnSequence: number;
|
|
221
|
-
receipt?: "
|
|
221
|
+
receipt?: "unavailable" | "required" | undefined;
|
|
222
222
|
}>>>>;
|
|
223
223
|
}, z.core.$strict>;
|
|
224
224
|
wake: z.ZodUnion<readonly [z.ZodObject<{
|
|
@@ -23,12 +23,17 @@ export type ActivitySlice = ActivityFactSlice;
|
|
|
23
23
|
export type { ActivityFact };
|
|
24
24
|
export type { TimelineFact } from "./timeline.js";
|
|
25
25
|
export declare function activitySlice(paths: AkumaPaths): Promise<ActivitySlice>;
|
|
26
|
-
export declare function readStatusFacts(paths: AkumaPaths, input: StatusFactInput): Promise<ActivitySlice["rows"]>;
|
|
26
|
+
export declare function readStatusFacts(paths: AkumaPaths, input: StatusFactInput, signal?: AbortSignal): Promise<ActivitySlice["rows"]>;
|
|
27
|
+
/** One live observation's successful raw input and decoded frontier, never a connection. */
|
|
28
|
+
export declare function createStatusFactReader(paths: AkumaPaths): {
|
|
29
|
+
clear(): void;
|
|
30
|
+
read(input: StatusFactInput, signal?: AbortSignal): Promise<ActivitySlice["rows"]>;
|
|
31
|
+
};
|
|
27
32
|
type LifeSnapshot = Pick<HeartSnapshot, "soul" | "latestBody" | "latestSession" | "latestKill"> & Readonly<{
|
|
28
33
|
hasPendingTell: boolean;
|
|
29
34
|
}>;
|
|
30
35
|
/** Lifecycle probes do not load narration, Tell bodies, or delivery histories. */
|
|
31
|
-
export declare function readLifeSnapshot(paths: AkumaPaths): Promise<LifeSnapshot>;
|
|
36
|
+
export declare function readLifeSnapshot(paths: AkumaPaths, signal?: AbortSignal): Promise<LifeSnapshot>;
|
|
32
37
|
export declare function recordTell(paths: AkumaPaths, tell: Omit<TellFact, "sequence" | "state" | "deliveries" | "binding">, options?: Readonly<{
|
|
33
38
|
interrupt?: boolean;
|
|
34
39
|
}>): Promise<Readonly<{
|