@astrosheep/keiyaku 4.6.3 → 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 +47 -11
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +8 -9
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +37 -25
- 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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-akuma
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Use when the work involves Akuma or Aku, or when you want other hands on
|
|
5
|
+
it: delegating a job, or fanning out research, checks, or other parallel
|
|
6
|
+
work.
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
# Keiyaku Akuma
|
|
@@ -15,6 +16,12 @@ shorter, world-local name.
|
|
|
15
16
|
|
|
16
17
|
## Call a new Akuma
|
|
17
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
|
+
|
|
18
25
|
The prompt is optional for prompt-free birth. Otherwise it is the new Akuma's
|
|
19
26
|
first prompt: give it as one argument, or use `-` to read stdin, never both.
|
|
20
27
|
Calls are detached by default: they return the new identity after birth without
|
|
@@ -22,7 +29,7 @@ waiting for the first answer. Use explicit `--wait <duration>` when this
|
|
|
22
29
|
invocation should block while observing that initial work. `--wait` only bounds
|
|
23
30
|
this command; it never stops the Akuma. Read `call --help` for flag syntax,
|
|
24
31
|
defaults, and action vocabulary.
|
|
25
|
-
|
|
32
|
+
To hand a Contract role to an Akuma, use the grant table in `keiyaku-workflow`.
|
|
26
33
|
|
|
27
34
|
The selected Akuma name is a reusable worker configuration, not an individual.
|
|
28
35
|
Calling it again creates an independent Akuma. Use different names for
|
|
@@ -33,34 +40,57 @@ capabilities, not merely for parallelism.
|
|
|
33
40
|
`--contract` only records the association. It does not tell the Akuma the
|
|
34
41
|
Contract or worktree. Put them in the prompt explicitly:
|
|
35
42
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
40
49
|
```
|
|
41
50
|
|
|
42
51
|
`--contract` does not choose a worktree. Use `--workdir <path>` when needed.
|
|
43
52
|
|
|
44
53
|
## Tell or ask an existing Akuma
|
|
45
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
|
+
|
|
46
62
|
`tell` admits the next instruction and returns its admission receipt; it does
|
|
47
63
|
not await an answer. `ask` admits a Tell and observes that exact answer,
|
|
48
64
|
unbounded unless `--wait` limits observation. Both require a prompt and accept
|
|
49
65
|
`--interrupt` to put down current work before admitting the new Tell. Schema
|
|
50
66
|
belongs only to `ask`; `tell --schema` and `tell --wait` refuse and point to
|
|
51
67
|
`ask`. A deadline never withdraws an admitted Tell. Read `tell --help` and
|
|
52
|
-
`ask --help` for
|
|
68
|
+
`ask --help` for the complete flag grammar.
|
|
53
69
|
|
|
54
70
|
## Observe work
|
|
55
71
|
|
|
72
|
+
```bash
|
|
73
|
+
keiyaku wait @deliverer @reviewer
|
|
74
|
+
keiyaku wait --all --timeout 30m @deliverer @reviewer
|
|
75
|
+
```
|
|
76
|
+
|
|
56
77
|
Use `wait` for one or more existing Akumas. The default is `--any`; use
|
|
57
78
|
`--all` for every selected Akuma. `--timeout` limits observation and does not
|
|
58
79
|
stop workers. A completed Akuma already counts, so repeating a wait can return
|
|
59
|
-
immediately. See `wait --help` for
|
|
60
|
-
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.
|
|
61
82
|
|
|
62
83
|
## Inspect and retrieve results
|
|
63
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
|
+
|
|
64
94
|
`status` shows the roster or one Akuma's workdir and effective actions.
|
|
65
95
|
`ls aku/` shows callable names; `ls "aku/*/*"` shows born workers.
|
|
66
96
|
`history --last` reads the latest complete answer; `history --id` reads an
|
|
@@ -69,10 +99,16 @@ move; see `history --help` for paging.
|
|
|
69
99
|
|
|
70
100
|
## Stop and branch
|
|
71
101
|
|
|
102
|
+
```bash
|
|
103
|
+
keiyaku kill @reviewer
|
|
104
|
+
keiyaku fork @reviewer --at turn/3
|
|
105
|
+
```
|
|
106
|
+
|
|
72
107
|
`kill` stops current work without admitting a Tell, deleting the Akuma, or
|
|
73
108
|
removing its history. `fork` creates a new Akuma from one exact retained
|
|
74
109
|
answered history point; the source is unchanged, and providers that cannot
|
|
75
|
-
fork report that refusal. See
|
|
110
|
+
fork report that refusal. See `kill --help` and `fork --help` for the
|
|
111
|
+
complete grammar.
|
|
76
112
|
|
|
77
113
|
## JavaScript automation
|
|
78
114
|
|
package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md
CHANGED
|
@@ -46,8 +46,8 @@ skeptics to break the finalists, and generate replacements only for the
|
|
|
46
46
|
identified weaknesses. Bound rounds and cost; "keep improving" is not a useful
|
|
47
47
|
stop condition.
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
Blind comparisons and adversarial checks need separate contexts. Create
|
|
50
|
+
separate Akuma for them. Reuse an identity for follow-up
|
|
51
51
|
investigation, not as a supposedly fresh judge of its own earlier answer.
|
|
52
52
|
|
|
53
53
|
## Public Entry And A Single Structured Turn
|
|
@@ -52,7 +52,7 @@ does not move without you.
|
|
|
52
52
|
| Observed shape | First response |
|
|
53
53
|
| --- | --- |
|
|
54
54
|
| Silent wedge: initial answer empty and worktree clean | Inspect status and history, then send one steering `tell`. If the worker remains unresponsive, `kill` and call a new Akuma; an empty answer alone is not proof the Contract failed. |
|
|
55
|
-
| Verdict record refused with `not-allowed` | Read the worker's analysis in history
|
|
55
|
+
| Verdict record refused with `not-allowed` | Read the worker's analysis in history. Record the verdict yourself if you did not deliver the candidate, or call a new Reviewer with the grant from `keiyaku-workflow` and have it inspect current work and record a fresh verdict. The refused request wrote no Contract testimony. |
|
|
56
56
|
| Review stale after changed candidate tender | Normal content-currentness result. Give the same Reviewer the changed diff and current terms with `tell`; have it re-examine and record current testimony. A target move alone does not stale review. |
|
|
57
57
|
| Target moved under the appointed worktree | Have the Deliverer inspect target movement and merge the target branch (main when selected) in that worktree when required; resolve conflicts there, then audit again. Do not resolve against a stale integration preview. |
|
|
58
58
|
| Typed refusal names its rule | Fix the named input or physical condition, then retry from a fresh observation. Do not repeat the same request blindly. |
|
|
@@ -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
|
|
|
@@ -205,7 +204,7 @@ waiting, the stated prerequisites remain; do not bind a duplicate Contract.
|
|
|
205
204
|
|
|
206
205
|
The holder now owns the lifecycle:
|
|
207
206
|
|
|
208
|
-
1. Start the work directly or delegate Tasks, Arc chapters, Akumas, or
|
|
207
|
+
1. Start the work directly or delegate Tasks, Arc chapters, Akumas, or Contract roles.
|
|
209
208
|
2. Run independent work in parallel and let it converge on the one acceptance
|
|
210
209
|
boundary.
|
|
211
210
|
3. Prepare and deliver the candidate.
|
|
@@ -38,13 +38,26 @@ to create parallel work.
|
|
|
38
38
|
Use `after` only when one `kei` requires another to be accepted first. Ordinary
|
|
39
39
|
overlap is not a dependency.
|
|
40
40
|
|
|
41
|
-
## 3.
|
|
41
|
+
## 3. Roles
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
A `kei` has three roles. They are responsibilities, not people, and one agent
|
|
44
|
+
may fill more than one of them, with one exception below.
|
|
45
|
+
|
|
46
|
+
- **Holder:** exactly one per `kei`. Owns the fulfillment loop and acceptance
|
|
47
|
+
until the Contract is accepted or abandoned. Handing work to others never
|
|
48
|
+
transfers this responsibility.
|
|
49
|
+
- **Deliverer:** produces the candidate in the appointed worktree and tenders
|
|
50
|
+
it with `deliver`.
|
|
51
|
+
- **Reviewer:** judges the complete Contract against its acceptance conditions
|
|
52
|
+
and records the verdict with `review`.
|
|
53
|
+
|
|
54
|
+
Review is independent when the Reviewer did not deliver the candidate under
|
|
55
|
+
review. That is the whole requirement. The holder may review its own `kei`; a
|
|
56
|
+
fresh Akuma is not what makes review independent. Keiyaku does not check who
|
|
57
|
+
reviews, so keeping the Reviewer apart from the Deliverer is the holder's duty.
|
|
58
|
+
|
|
59
|
+
Any role may be filled directly or handed to an Akuma. Hand one over when other
|
|
60
|
+
hands help the work, not to make review count.
|
|
48
61
|
|
|
49
62
|
## 4. Lifecycle
|
|
50
63
|
|
|
@@ -59,9 +72,9 @@ Each act changes a different part of the world:
|
|
|
59
72
|
audit; when it matters, merge the target branch (main when selected) in the
|
|
60
73
|
worktree and resolve conflicts there before auditing.
|
|
61
74
|
- **Audit:** Previews the candidate and target without tendering or claiming.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
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.
|
|
65
78
|
- **Deliver:** Captures a tender and integration against the observed target;
|
|
66
79
|
journal gains a delivered candidate. Ready prerequisites and gates trigger
|
|
67
80
|
placement and claim in this invocation; otherwise the candidate waits.
|
|
@@ -78,31 +91,30 @@ Placement judges declared gates, not the producer's identity. Review does not
|
|
|
78
91
|
replace Verification; audit never requests placement. Read the final receipt
|
|
79
92
|
for stops and reconciliation lag after an admitted act.
|
|
80
93
|
|
|
81
|
-
## 5.
|
|
94
|
+
## 5. Handing A Role To An Akuma
|
|
82
95
|
|
|
83
96
|
This is the one commissioning map. `call --help` owns the exact action
|
|
84
|
-
vocabulary and default set.
|
|
97
|
+
vocabulary and default set. The flagship acting directly needs no grant.
|
|
98
|
+
Birth freezes an Akuma's actions; `--contract` records association, not
|
|
99
|
+
authority.
|
|
85
100
|
|
|
86
|
-
|
|
|
101
|
+
| Role | Grant at birth | Return |
|
|
87
102
|
| --- | --- | --- |
|
|
88
|
-
| Holder |
|
|
89
|
-
| Deliverer | The ordinary baseline
|
|
90
|
-
| Reviewer |
|
|
103
|
+
| Holder | The actions the delegated loop will perform; include `contract.review` when this holder will review. Commission with the `kei`, current Arc when one exists, appointed worktree, and holder duties. | Acceptance or abandonment, with receipts. |
|
|
104
|
+
| Deliverer | The ordinary baseline: every Task mutation, Contract audit and delivery, and Akuma management. `keiyaku -C <repo> call worker --alias @deliverer --contract <kei/...> --workdir <appointed-path> -` | The delivery receipt. |
|
|
105
|
+
| Reviewer | `--allowed contract.review`: `keiyaku -C <repo> call review-akuma --alias @reviewer --contract <kei/...> --workdir <appointed-path> --allowed contract.review -` | The verdict receipt. Without the grant, `not-allowed` refuses and no verdict is recorded. |
|
|
91
106
|
|
|
92
|
-
An Archetype's explicit allowed set replaces the ordinary baseline
|
|
107
|
+
An Archetype's explicit allowed set replaces the ordinary baseline; check
|
|
93
108
|
`status` for effective actions. `tell` and `fork` cannot add a grant to a live
|
|
94
|
-
Akuma
|
|
95
|
-
parent's actions.
|
|
96
|
-
|
|
97
|
-
## 6. Delegate the Work
|
|
109
|
+
Akuma, so call a fresh one with the grant. Nested calls cannot exceed their
|
|
110
|
+
direct parent's actions.
|
|
98
111
|
|
|
99
112
|
Commission with a clear objective, current Arc when one exists, appointed
|
|
100
|
-
worktree, and expected result.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
command help for exact syntax.
|
|
113
|
+
worktree, and expected result. Never ask the Akuma that delivered a candidate
|
|
114
|
+
to review it. Use `keiyaku-akuma` for invocation and observation, and command
|
|
115
|
+
help for exact syntax.
|
|
104
116
|
|
|
105
|
-
##
|
|
117
|
+
## 6. Decide What Happens Next
|
|
106
118
|
|
|
107
119
|
The holder checks candidate, verification, review, prerequisites, and gates.
|
|
108
120
|
|
|
@@ -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);
|