@astrosheep/keiyaku 4.5.27 → 4.5.28

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 (40) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +82 -163
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +153 -78
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +68 -64
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +115 -146
  9. package/build/src/akuma/akuma-handle.d.ts +1 -0
  10. package/build/src/akuma/akuma-handle.js +4 -1
  11. package/build/src/akuma/akuma-observe.d.ts +6 -0
  12. package/build/src/akuma/akuma-observe.js +3 -1
  13. package/build/src/akuma/akuma.d.ts +1 -0
  14. package/build/src/akuma/akuma.js +1 -0
  15. package/build/src/akuma/fleet-execution.d.ts +7 -1
  16. package/build/src/akuma/fleet-execution.js +12 -11
  17. package/build/src/akuma/fleet-observation.d.ts +3 -0
  18. package/build/src/akuma/identity.js +11 -9
  19. package/build/src/alias/index.js +3 -3
  20. package/build/src/cli/commands/akuma-invoke.js +13 -4
  21. package/build/src/cli/commands/akuma.js +9 -15
  22. package/build/src/cli/commands/contract-help.d.ts +1 -0
  23. package/build/src/cli/commands/contract-help.js +1 -0
  24. package/build/src/cli/invoke.js +1 -1
  25. package/build/src/cli/render/akuma-activity.js +6 -1
  26. package/build/src/cli/render/akuma.d.ts +9 -0
  27. package/build/src/cli/render/akuma.js +48 -8
  28. package/build/src/identity/normalize.d.ts +3 -0
  29. package/build/src/identity/normalize.js +10 -0
  30. package/build/src/identity/selector.d.ts +1 -0
  31. package/build/src/identity/selector.js +15 -4
  32. package/build/src/library/address.js +2 -2
  33. package/build/src/library/akuma-creation.d.ts +1 -1
  34. package/build/src/library/akuma-creation.js +10 -52
  35. package/build/src/library/composition.d.ts +2 -1
  36. package/build/src/library/fleet.d.ts +2 -1
  37. package/build/src/library/fleet.js +7 -3
  38. package/build/src/library/keiyaku.d.ts +2 -1
  39. package/build/src/protocol/completion.js +9 -2
  40. package/package.json +1 -1
@@ -1,100 +1,104 @@
1
1
  ---
2
2
  name: keiyaku-task
3
3
  description: >-
4
- Use for task management: organizing work of three or more steps and
5
- tracking it as it progresses.
4
+ Must read when using Tasks for durable work planning, decomposition, or
5
+ dependencies.
6
6
  ---
7
7
 
8
8
  # Keiyaku Task
9
9
 
10
- ## What A Task Is Not
10
+ A Task is durable planning memory. It records work, decomposition, and
11
+ relationships that must remain after the current conversation. Task is an
12
+ independent product; it is not a Contract, Arc, Akuma, permission, acceptance
13
+ boundary, or fulfillment lifecycle.
11
14
 
12
- A Task remembers a plan: what is intended, what depends on what, what was
13
- decided about sequence. It grants nothing — no acceptance, no permission, no
14
- scope, no fulfillment loop. Whoever holds a Contract's loop uses Tasks when the
15
- plan is worth remembering and skips them when it is not; nothing binds Tasks to
16
- Arcs, Contracts, or Akuma as a package.
15
+ ## 1. When To Use A Task
17
16
 
18
- ## Lifecycle
17
+ Use a Task when the plan or dependency must outlive the current conversation.
18
+ Skip it when the work is small and no durable planning memory is needed.
19
19
 
20
- ```text
21
- open -> in_progress -> done | drop
22
- | |
23
- +-> on_hold <-+
24
- ```
20
+ - Use a `kei` for one independently acceptable outcome.
21
+ - Use an Arc for a chapter inside one `kei`.
22
+ - Use a Task for decomposition or dependency memory.
23
+ - Do not create a Task just to mirror a `kei`.
24
+
25
+ A Task may exist without a Contract. Associating a Task with a `kei` does not
26
+ transfer the Contract's holder, acceptance, or lifecycle to the Task.
27
+
28
+ ## 2. Relationships And Parallel Work
29
+
30
+ Independent Tasks may start and progress in parallel when their dependencies
31
+ allow it.
32
+
33
+ Use the relationships for their actual meanings:
34
+
35
+ - `needs` means this Task must wait for another Task to become terminal.
36
+ - `parent` groups decomposition; it does not create a dependency.
37
+ - `supersedes` points to work replaced by this Task.
38
+ - `relates` records a connection without affecting readiness.
39
+
40
+ Only `needs` orders work. Do not add it because Tasks touch the same Region or
41
+ because one Task is related to another. A terminal Task releases its dependents.
42
+ An `on_hold` Task is deliberately paused; it is neither ready nor blocked.
25
43
 
26
- Use `ready` for open tasks whose `needs` are terminal. `blocked` reports open
27
- or in-progress tasks with unresolved needs. `on_hold` appears in neither view.
28
- Both `done` and `drop` release dependents. `doctor` diagnoses the complete
29
- world and never repairs it.
44
+ ## 3. Task Commands
30
45
 
31
- ## Common Commands
46
+ Create and inspect Tasks:
32
47
 
33
48
  ```bash
34
- keiyaku task add "title"
35
- keiyaku task add "title" --priority 1 --needs <task-id>
36
- keiyaku task add --namespace <ns> -
49
+ keiyaku task add "<title>"
50
+ keiyaku task add "<title>" --priority 1 --needs <task-id>
37
51
  keiyaku task show <task-id>
38
52
  keiyaku task ls
39
- keiyaku task ls --closed
40
- keiyaku task ls --all --world
41
53
  keiyaku task ready
42
54
  keiyaku task blocked
43
55
  keiyaku task tree <task-id>
44
56
  keiyaku task doctor
45
57
  ```
46
58
 
47
- `ls`, `ready`, and `blocked` use the current namespace; add `--world` to
48
- observe the complete Task world. `show`, `tree`, `update`, and lifecycle
49
- commands require a complete TaskId and never infer namespace.
59
+ Use complete Task IDs for targeted commands. `ls`, `ready`, and `blocked` use
60
+ the current namespace; use `--world` to inspect the complete Task world.
50
61
 
51
- ## Mutations
62
+ Change lifecycle state:
52
63
 
53
64
  ```bash
54
65
  keiyaku task start <task-id>...
55
66
  keiyaku task stop <task-id>
56
- keiyaku task hold <task-id>
67
+ keiyaku task hold <task-id>...
57
68
  keiyaku task resume <task-id>
58
69
  keiyaku task done <task-id>...
59
- keiyaku task drop <task-id>... [--note <text>]
60
- keiyaku task update <task-id> --title <text>
61
- keiyaku task context [<namespace>]
70
+ keiyaku task drop <task-id>... --note "<reason>"
62
71
  ```
63
72
 
64
- Relations are explicit facts: `needs` orders work, `parent` groups it,
65
- `supersedes` navigates replacement, and `relates` does not affect readiness.
66
- `task start` accepts one or more complete TaskIds. A single ID keeps the
67
- single-mutation result; multiple IDs use the ordered batch result, continue
68
- after per-Task refusals, and preserve retry-over-refusal exit precedence.
73
+ Use `done` when the Task is complete. Use `drop` when it will not be done.
74
+ Both terminal states release dependent Tasks. Use `hold` for a deliberate pause,
75
+ not for an unresolved dependency; unresolved `needs` appear in `blocked`.
69
76
 
70
- ## Batch Create Or Modify
71
-
72
- Use `task compose -` to create and modify multiple Tasks in one planning
73
- document. Its input grammar is documented by the Task CLI owner:
77
+ Update a Task without changing its lifecycle:
74
78
 
75
79
  ```bash
76
- keiyaku task compose - <<'EOF'
77
- ns=feature
78
-
79
- + Parent
80
- as = parent
81
- state = in_progress
82
- pri = 0
83
- body <<BODY
84
- Parent body.
85
- BODY
86
-
87
- + Child
88
- parent = ^parent
89
- needs = @task/existing
90
- EOF
80
+ keiyaku task update <task-id> --title "<title>"
81
+ keiyaku task update <task-id> --body "<body>"
82
+ keiyaku task update <task-id> --needs <task-id>
91
83
  ```
92
84
 
93
- Use `--plan` to inspect aliases, admission order, and body byte previews without
94
- writing. New `+ Title` nodes may declare `state = open|in_progress|on_hold|done|drop`
95
- as their initial state; omitted state is `open`. Existing `@task/...` nodes cannot
96
- declare state. Aliases are nonempty single-line tokens containing neither
97
- Unicode whitespace nor comma; references use `^alias`. Compose does not change
98
- the lifecycle state of pre-existing Tasks. Each changed Task is admitted
99
- independently; an incomplete result returns a reusable draft for the remaining
100
- batch and preserves each new node's declared state.
85
+ Use `task compose -` when several Tasks and their relationships should be
86
+ planned or admitted together. Use `--plan` to inspect the composition without
87
+ writing it.
88
+
89
+ ## 4. After Creating A Task
90
+
91
+ Read the returned Task identity. Then:
92
+
93
+ 1. Start ready work.
94
+ 2. Run independent Tasks in parallel.
95
+ 3. Add or remove relationships when the plan changes.
96
+ 4. Hold work that is deliberately paused.
97
+ 5. Mark completed work `done`, or mark abandoned work `drop` with a reason.
98
+ 6. Use `ready`, `blocked`, `tree`, or `doctor` to rebuild the current view.
99
+
100
+ Task records planning memory. It does not perform the work, claim acceptance,
101
+ assign a holder, or decide what a Contract may accept.
102
+
103
+ Read `keiyaku-bind` for Contract authoring and `keiyaku-workflow` for Contract
104
+ lifecycle.
@@ -1,151 +1,120 @@
1
1
  ---
2
2
  name: keiyaku-workflow
3
3
  description: >-
4
- Use when deciding whether Keiyaku work needs a Contract or Arcs, how to
5
- delegate it, or what to do next after a handoff: steer, assess a delivery,
6
- request another round, or land.
4
+ Must read before binding a `kei` (Contract) or when acting as its holder.
5
+ Use when deciding when to bind a kei, how to shape and hold it, how to
6
+ delegate its work, and how to accept, amend, or end it.
7
7
  ---
8
8
 
9
- # Holding a fulfillment loop
10
-
11
- You are the loop-holder: the one reader of this skill. Flagship and
12
- whole-loop delegate are the same reader — same decisions, same tools,
13
- no special role or permission either way.
14
-
15
- The state you steer: a Contract moves `waiting -> bound -> tendered ->
16
- claimed | abandoned`; claimed and abandoned are terminal. Prerequisites
17
- and declared gates block placement, never delivery admission. Deliver
18
- and a satisfied review each request placement; placement claims only
19
- when every current obligation permits.
20
-
21
- Routing. Authoring a Contract — its boundary, terms, gates — is
22
- keiyaku-bind. Commission, call, tell, wait, permission, and history
23
- mechanics are keiyaku-akuma. Attention across many waiting lanes is
24
- keiyaku-babysit. Seat procedure travels with the worktree: the
25
- generated seat skill in each appointment tells the Deliverer and
26
- Reviewer what to do. Exact grammar for any command is that command's
27
- help, nowhere else.
28
-
29
- ## Decision 1 — hold or delegate
30
-
31
- Take the lightest shape that carries the work. Direct work may skip a
32
- Contract entirely. Bounded mechanical work may take a Contract with no
33
- review gate. Tasks and Arcs are optional planning, never ceremony owed
34
- to the tool.
35
-
36
- The shape is not fixed at the start. Work begun directly that grows
37
- beyond expectation escalates midstream: bind a Contract then, and
38
- carry the change you already have into the appointed worktree as the
39
- candidate-in-progress. Nothing is lost by starting light; the only
40
- mistake is continuing an oversized effort outside any acceptance
41
- boundary because it happened to start there.
42
-
43
- Hold the loop yourself when you will decompose or implement. Delegate
44
- the whole loop when you steer at direction level: one commission hands
45
- one Aku the entire loop. Delegation changes who decides, not what
46
- exists — it creates no role, state, or journal fact. A whole-loop
47
- commission uses Contract association plus an explicit repository
48
- working directory; the automatic Contract-worktree working directory
49
- is for seat commissions only. Once delegated, steer through the
50
- holder, never around it. The delegate owes decisions and coordination,
51
- and may open Tasks, Arcs, and seat commissions beneath itself.
52
-
53
- ## Decision 2 — shape the work
54
-
55
- Cut by what must be independently acceptable. Multiple independently
56
- acceptable outcomes are separate Contracts. One acceptance boundary
57
- whose work still has chapters may use Arcs — chapters inside a single
58
- acceptance, never separately placeable. Decomposition and dependency
59
- memory that must outlive a conversation is a Task. The failure this
60
- decision prevents: an oversized boundary handed to one Deliverer as a
61
- single ordinary assignment, with no chapters and no durable plan.
62
-
63
- Authoring the Contract itself belongs to keiyaku-bind. A landing
64
- dependency — this Contract's placement genuinely requires that one
65
- landed — is a real `after` relation. Ordinary overlap is not: Regions
66
- are planning evidence for your scheduling eye, never ownership and
67
- never a gate.
68
-
69
- ## Decision 3 — commission seats
70
-
71
- A commission names one Contract, one seat, one worktree, and the
72
- capabilities that seat needs. A Deliverer owes a candidate; a Reviewer
73
- owes independent testimony. Grant only the actions required by that
74
- duty and verify them at dispatch. A self-recording Reviewer needs
75
- `contract.review` and therefore cannot be `--readonly`; use that flag
76
- only when another actor records the verdict. The configuration grammar
77
- is keiyaku-akuma's and the command's help.
78
-
79
- The prompt conveys the rest, in words this literal:
80
-
81
- Contract: <contract>
82
- Seat: Deliverer (or Reviewer)
83
- Worktree: <exact path>
84
- Read first:
85
- - .keiyaku/KEIYAKU.md
86
- - <exact governing owner-law paths>
87
- - <exact relevant source paths>
88
- This round: <one-sentence objective>
89
-
90
- A commission directs the round; it cannot amend acceptance. Standing
91
- acceptance is only the journaled terms and their amendments.
92
-
93
- Reviewer reuse is the default within one Contract while the judgment
94
- frame stays sound; a new Contract gets a new Reviewer.
95
-
96
- ## Decision 4 — adjudicate returns
97
-
98
- Review is two-valued: satisfied or unsatisfied, testified over the
99
- complete current candidate or document subject. Satisfied requests
100
- placement and may be the invocation that claims; unsatisfied never
101
- places. When satisfied cannot be reached, the summary names what
102
- blocks it: the candidate, the required evidence, or the terms as
103
- written. Advice beyond acceptance may accompany testimony and changes
104
- no verdict. A returned Reviewer verdict is transported faithfully into
105
- testimony, or a fresh independent review is commissioned — never
106
- paraphrased into a different verdict. A Contract with no review gate
107
- neither requires nor owes any review.
108
-
109
- Deliver records the intended candidate, freshly prepares it against
110
- the target as the target exists for that invocation, runs or reuses
111
- Verification, and requests placement. A clean worktree delivers its
112
- HEAD; a dirty delivery captures the complete non-ignored state as an
113
- immutable commit without moving the branch or the real index — a
114
- prior git commit is optional shaping, never a prerequisite. Deliver
115
- never satisfies a review gate.
116
-
117
- Conflict materialization projects an uncommitted merge; it does not resolve
118
- its contents or record a delivery. After editing the final worktree bytes,
119
- `deliver --include-dirty` can capture them even while the real index still
120
- reports `UU`. No `git add` or commit is required, and capture preserves the
121
- real index. The candidate includes the complete non-ignored worktree, not
122
- just the Contract's Region or the conflict paths. Candidate capture and target
123
- placement are separate: this authorization does not permit overwriting
124
- blocking changes in the target checkout.
125
-
126
- Audit observes: prospective candidate, integration, Verification,
127
- diff, target. It records no candidate and satisfies no gate.
128
-
129
- Evidence goes stale by subject identity: a changed candidate or
130
- amended terms stales the testimony over that subject. Amend only
131
- while the same objective and acceptance boundary remain truthful —
132
- amendment reshapes terms inside the same promise. When the objective
133
- or the boundary itself has changed, abandon and bind a truthful new
134
- Contract; do not steer old terms onto a different delivery. Abandon
135
- ends a Contract without moving the target.
136
-
137
- ## Decision 5 — schedule landing
138
-
139
- You schedule overlapping Contracts; nothing persists an ordering — no
140
- train exists in the tool. When the target has moved, prepare the
141
- current-target integration before the authoritative review. A
142
- content-equivalent preparation retains standing testimony; a changed
143
- conflict resolution stales it. Target movement requires fresh deliver
144
- or audit preparation.
145
-
146
- A placement refusal preserves the candidate and the testimony and
147
- leaves target and checkout untouched: resolve the blocking obligation
148
- and request placement again. Reconcile finishes accepted lagging
149
- effects; it does not retry a placement refusal. Rebuild your picture
150
- at any time from the read surfaces — status, show, region — whose
151
- grammar lives in their help.
9
+ # Keiyaku Workflow
10
+
11
+ This skill manages a `kei` (Contract) from preparation to completion.
12
+
13
+ ## 1. Prepare Before Binding
14
+
15
+ Before `bind`, settle the information that makes the `kei` truthful:
16
+
17
+ - objective and intended outcome;
18
+ - design and approach;
19
+ - affected Region;
20
+ - acceptance conditions;
21
+ - verification and required evidence;
22
+ - prerequisites;
23
+ - holder.
24
+
25
+ If the design, approach, or acceptance conditions are still open, do not bind.
26
+ Resolve them with their owner first. Private implementation details may remain
27
+ for the Deliverer; the public meaning and acceptance boundary may not.
28
+
29
+ Bind independent `kei`s in parallel. Do not split one acceptance boundary just
30
+ to create parallel work.
31
+
32
+ ## 2. Split the Work
33
+
34
+ Use these rules:
35
+
36
+ - Separate `kei`s have independently acceptable outcomes.
37
+ - An Arc is a chapter of one `kei`; it is not separately accepted.
38
+ - A Task stores decomposition or dependencies that must outlive the current
39
+ conversation.
40
+
41
+ Use `after` only when one `kei` requires another `kei` to be completed first.
42
+ Ordinary overlap is not a dependency.
43
+
44
+ ## 3. Hold the `kei`
45
+
46
+ Every `kei` has exactly one holder. The holder owns it until completion or
47
+ termination, coordinates its work, delegates when useful, and is responsible
48
+ for acceptance.
49
+
50
+ The holder may work directly or delegate Akumas, Deliverers, Reviewers, Tasks,
51
+ or Arcs. An Akuma holder must receive the `kei`, current Arc when one exists,
52
+ worktree, and holder responsibilities in its prompt, and must have
53
+ `contract.*` and `akuma.*`.
54
+
55
+ ## 4. Lifecycle
56
+
57
+ ```text
58
+ bind -> tender -> gates and prerequisites pass -> automatic claim
59
+ \\-> abandon
60
+ ```
61
+
62
+ - `bind` creates the `kei` with its terms, acceptance conditions, gates, and
63
+ dependencies.
64
+ - `tender` submits the candidate for acceptance.
65
+ - After tender, the `kei` is claimed automatically when its prerequisites and
66
+ every required gate pass.
67
+ - `abandon` ends a `kei` without claiming it.
68
+ - A claimed or abandoned `kei` is terminal.
69
+
70
+ The holder may continue work and tender again while the `kei` is not terminal.
71
+
72
+ ## 5. Gates
73
+
74
+ A gate is a named acceptance obligation. A tendered `kei` cannot be claimed
75
+ until every selected gate has satisfied evidence.
76
+
77
+ Bind gate options:
78
+
79
+ ```bash
80
+ keiyaku bind --gates <name,...> -
81
+ keiyaku bind --gates "" -
82
+ keiyaku bind --gates reviewed -
83
+ ```
84
+
85
+ - Omitting `--gates` selects `gates.default`; when no default bundle exists,
86
+ it selects `reviewed`.
87
+ - `--gates <name,...>` selects gate names and configured bundles. Bundles
88
+ expand to their configured gates.
89
+ - `--gates ""` binds the `kei` with no gates.
90
+ - `--gates reviewed` selects the `reviewed` gate directly.
91
+
92
+ Gates are acceptance requirements, not work assignments. The Deliverer
93
+ produces the candidate, the relevant producer supplies evidence, and the holder
94
+ coordinates the remaining work.
95
+
96
+ ## 6. Delegate the Work
97
+
98
+ Delegate with a clear owner, objective, worktree, and expected result. Include
99
+ the current Arc when one exists. A Deliverer produces the candidate. A Reviewer
100
+ checks it against the `kei`'s acceptance conditions and returns evidence.
101
+ Delegation does not transfer the holder's responsibility.
102
+
103
+ Use `keiyaku-akuma` for Akuma invocation, telling, waiting, permissions, and
104
+ history. Use command help for exact syntax.
105
+
106
+ ## 7. Decide What Happens Next
107
+
108
+ The holder checks the tendered candidate, verification, review evidence,
109
+ prerequisites, and gates.
110
+
111
+ - If everything passes, automatic claim completes the `kei`.
112
+ - If something is missing, continue the work or delegate the next chapter.
113
+ - Amend when the objective and acceptance boundary remain the same but the
114
+ terms need to change.
115
+ - Abandon and bind a new `kei` when the objective or acceptance boundary has
116
+ changed.
117
+
118
+ For Contract authoring, read `keiyaku-bind`. For Akuma delegation, read
119
+ `keiyaku-akuma`. For supervising many waiting `kei`s, read
120
+ `keiyaku-babysit`.
@@ -78,6 +78,7 @@ export declare class AkumaHandle {
78
78
  tellOutcome(tellId: string, options?: Readonly<{
79
79
  timeoutMs?: number;
80
80
  signal?: AbortSignal;
81
+ observe?: (observation: import("./akuma-observe.js").LiveStatusObservation) => void | Promise<void>;
81
82
  }>): Promise<Readonly<{
82
83
  reason: WaitReason;
83
84
  outcome: TurnOutcome | null;
@@ -8,7 +8,7 @@ import { resolveProviderExecution } from "./providers/index.js";
8
8
  import { publishAkuma } from "./publication.js";
9
9
  import { spawnAkumaBody } from "./body.js";
10
10
  import { AkumaNotBornError, AkumaProviderError } from "./akuma-errors.js";
11
- import { bornStatus, defaultWaitComplete, readWaitComplete, waitForObservation, } from "./akuma-observe.js";
11
+ import { bornStatus, bornLiveStatus, defaultWaitComplete, readWaitComplete, waitForObservation, } from "./akuma-observe.js";
12
12
  const CALL_EXECUTION = Symbol("akuma-call-execution");
13
13
  function diagnostic(error) {
14
14
  return error instanceof Error ? error.message : String(error);
@@ -209,6 +209,9 @@ export class AkumaHandle {
209
209
  if (tell === null)
210
210
  throw new AkumaProviderError(`recorded Tell ${tellId} is missing from Heart`);
211
211
  const outcome = await this.boundTellOutcome(tell);
212
+ if (options.observe !== undefined) {
213
+ await options.observe(await bornLiveStatus(this.paths, this.id, { aperture: "monitoring", admittedTellId: tellId }));
214
+ }
212
215
  return { outcome, terminalWithoutTurn: tell.state === "told" && tell.binding === undefined };
213
216
  },
214
217
  complete: (observed) => observed.outcome !== null || observed.terminalWithoutTurn,
@@ -15,6 +15,12 @@ export type BudgetedStatusObservation = Readonly<{
15
15
  export type LiveStatusObservation = BudgetedStatusObservation & Readonly<{
16
16
  rows: readonly ActivityRow[];
17
17
  }>;
18
+ /** Internal live companion for an observation loop; it is not a public result. */
19
+ export declare function bornLiveStatus(paths: AkumaPaths, expected: AkuId, input: Readonly<{
20
+ aperture: "monitoring" | "receipt";
21
+ ordinaryBudget?: number;
22
+ admittedTellId?: string;
23
+ }>): Promise<LiveStatusObservation>;
18
24
  export declare function bornStatus(paths: AkumaPaths, expected: AkuId, input: Readonly<{
19
25
  aperture: "monitoring" | "receipt";
20
26
  ordinaryBudget?: number;
@@ -56,7 +56,8 @@ async function bornObservation(paths, expected, read, snapshot) {
56
56
  claim?.release();
57
57
  }
58
58
  }
59
- async function bornLiveStatus(paths, expected, input) {
59
+ /** Internal live companion for an observation loop; it is not a public result. */
60
+ export async function bornLiveStatus(paths, expected, input) {
60
61
  if (input.ordinaryBudget !== undefined && (!Number.isSafeInteger(input.ordinaryBudget) || input.ordinaryBudget < 0))
61
62
  throw new TypeError("ordinary budget must be a nonnegative safe integer");
62
63
  const { snapshot, soul, currentLife } = await bornObservation(paths, expected, () => readLifeSnapshot(paths));
@@ -74,6 +75,7 @@ async function bornLiveStatus(paths, expected, input) {
74
75
  status: {
75
76
  id: soul.id,
76
77
  life: currentLife,
78
+ cwd: soul.cwd,
77
79
  allowed: soul.allowed,
78
80
  ...(soul.readonly === undefined ? {} : { readonly: soul.readonly }),
79
81
  ...(resumeUnsupported ? { strandedReason: "resume-unsupported" } : {}),
@@ -32,6 +32,7 @@ export declare const akumaStatusSchema: z.ZodObject<{
32
32
  asleep: "asleep";
33
33
  stranded: "stranded";
34
34
  }>;
35
+ cwd: z.ZodOptional<z.ZodString>;
35
36
  allowed: z.ZodPipe<z.ZodArray<z.ZodEnum<{
36
37
  "task.add": "task.add";
37
38
  "task.addDocument": "task.addDocument";
@@ -26,6 +26,7 @@ export const akumaStatusSchema = z
26
26
  .object({
27
27
  id: akumaIdSchema,
28
28
  life: z.enum(["running", "asleep", "stranded", "hung", "untidy", "killed"]),
29
+ cwd: z.string().optional(),
29
30
  allowed: allowedActionsSchema,
30
31
  readonly: readonlySchema.optional(),
31
32
  timeline: activitySnapshotSchema,
@@ -1,4 +1,5 @@
1
- import { type AkumaStatus } from "./akuma.js";
1
+ import { type AkumaStatus, type TellResult } from "./akuma.js";
2
+ import { type LiveStatusObservation } from "./akuma-observe.js";
2
3
  import type { ActivityRow } from "./projection.js";
3
4
  import { type DispatchAssociation } from "./dispatch-association.js";
4
5
  import type { AkumaAlias } from "../identity/selector.js";
@@ -40,6 +41,10 @@ export type WaitExecutionInput = Readonly<{
40
41
  observe?: (observed: readonly WaitObservedAkuma[]) => void;
41
42
  }>;
42
43
  export declare function executeWaitAkuma(input: WaitExecutionInput): Promise<AkumaWaitResult>;
44
+ export type TellWaitObserver = Readonly<{
45
+ admitted?: (tell: TellResult, id: AkumaStatus["id"]) => void | Promise<void>;
46
+ observe?: (observation: LiveStatusObservation) => void | Promise<void>;
47
+ }>;
43
48
  export type TellExecutionInput = Readonly<{
44
49
  path: WorldRoot;
45
50
  id: AkumaStatus["id"];
@@ -48,6 +53,7 @@ export type TellExecutionInput = Readonly<{
48
53
  recordedAt?: string;
49
54
  initiator?: string;
50
55
  signal?: AbortSignal;
56
+ onObserve?: TellWaitObserver;
51
57
  }>;
52
58
  export declare function executeTellAkuma(input: TellExecutionInput): Promise<AkumaTellResult>;
53
59
  export declare function executeTellWaitAkuma(input: TellExecutionInput & Readonly<{
@@ -126,6 +126,15 @@ export async function executeTellAkuma(input) {
126
126
  tell,
127
127
  });
128
128
  }
129
+ function tellWaitObservation(observed) {
130
+ if (observed.outcome === null)
131
+ return observed.reason === "deadline" ? { reason: "deadline" } : { reason: "unanswered" };
132
+ if (observed.outcome.kind === "answered")
133
+ return { reason: "answered", answer: observed.outcome.answerJson ?? observed.outcome.answer };
134
+ if (observed.outcome.kind === "failed")
135
+ return { reason: "failed", diagnostic: observed.outcome.diagnostic };
136
+ throw new AkumaDecodeError(observed.outcome.diagnostic, observed.outcome.answer);
137
+ }
129
138
  export async function executeTellWaitAkuma(input) {
130
139
  input.signal?.throwIfAborted();
131
140
  const handle = source(input.path).selectHandle({ id: input.id });
@@ -145,6 +154,7 @@ export async function executeTellWaitAkuma(input) {
145
154
  throw new AkumaProviderError(`Tell interrupt unavailable: ${admission.evidence}`);
146
155
  if (admission.kind === "not-born")
147
156
  throw new AkumaNotBornError(input.id);
157
+ await input.onObserve?.admitted?.(await handle.admittedReceipt(admission.tell.id), input.id);
148
158
  // The wake runs behind the window; a settled wake is preferred, otherwise the
149
159
  // receipt reports the admitted Tell as it stands when the window closes.
150
160
  let settled;
@@ -154,18 +164,9 @@ export async function executeTellWaitAkuma(input) {
154
164
  const observed = await handle.tellOutcome(admission.tell.id, {
155
165
  timeoutMs: input.timeoutMs,
156
166
  ...(input.signal === undefined ? {} : { signal: input.signal }),
167
+ ...(input.onObserve?.observe === undefined ? {} : { observe: input.onObserve.observe }),
157
168
  });
158
- const observation = observed.outcome === null
159
- ? observed.reason === "deadline"
160
- ? { reason: "deadline" }
161
- : { reason: "unanswered" }
162
- : observed.outcome.kind === "answered"
163
- ? { reason: "answered", answer: observed.outcome.answerJson ?? observed.outcome.answer }
164
- : observed.outcome.kind === "failed"
165
- ? { reason: "failed", diagnostic: observed.outcome.diagnostic }
166
- : (() => {
167
- throw new AkumaDecodeError(observed.outcome.diagnostic, observed.outcome.answer);
168
- })();
169
+ const observation = tellWaitObservation(observed);
169
170
  const tell = settled ?? (await handle.admittedReceipt(admission.tell.id));
170
171
  return fleetResultSchemas.tellWait.parse({ akuma: input.id, tell, observation });
171
172
  }
@@ -10,6 +10,7 @@ declare const akumaObservationSchema: z.ZodObject<{
10
10
  asleep: "asleep";
11
11
  stranded: "stranded";
12
12
  }>;
13
+ cwd: z.ZodOptional<z.ZodString>;
13
14
  allowed: z.ZodPipe<z.ZodArray<z.ZodEnum<{
14
15
  "task.add": "task.add";
15
16
  "task.addDocument": "task.addDocument";
@@ -481,6 +482,7 @@ declare const akumaWaitResultSchema: z.ZodObject<{
481
482
  asleep: "asleep";
482
483
  stranded: "stranded";
483
484
  }>;
485
+ cwd: z.ZodOptional<z.ZodString>;
484
486
  allowed: z.ZodPipe<z.ZodArray<z.ZodEnum<{
485
487
  "task.add": "task.add";
486
488
  "task.addDocument": "task.addDocument";
@@ -1173,6 +1175,7 @@ export declare const fleetResultSchemas: {
1173
1175
  asleep: "asleep";
1174
1176
  stranded: "stranded";
1175
1177
  }>;
1178
+ cwd: z.ZodOptional<z.ZodString>;
1176
1179
  allowed: z.ZodPipe<z.ZodArray<z.ZodEnum<{
1177
1180
  "task.add": "task.add";
1178
1181
  "task.addDocument": "task.addDocument";