@astrosheep/keiyaku 2.8.5 → 2.9.1
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/README.md +35 -15
- package/build/.tsbuildinfo +1 -1
- package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
- package/build/agents/harness/control-types.js +1 -0
- package/build/agents/harness/execution-handle.js +23 -3
- package/build/agents/harness/index.js +6 -607
- package/build/agents/harness/outcome.js +141 -0
- package/build/agents/harness/projection.js +310 -0
- package/build/agents/harness/router.js +201 -0
- package/build/agents/harness/runtime.js +2 -1
- package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
- package/build/agents/launch-snapshot/resolve.js +72 -0
- package/build/agents/opencode-sdk.js +24 -3
- package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
- package/build/agents/providers/claude-agent-sdk/events.js +218 -0
- package/build/agents/providers/claude-agent-sdk/session.js +158 -0
- package/build/agents/providers/codex-app-server/adapter.js +347 -0
- package/build/agents/providers/codex-app-server/events.js +352 -0
- package/build/agents/providers/codex-app-server/session.js +266 -0
- package/build/agents/providers/codex-sdk.js +23 -5
- package/build/agents/providers/opencode-sdk/adapter.js +344 -0
- package/build/agents/providers/opencode-sdk/events.js +354 -0
- package/build/agents/providers/opencode-sdk/session.js +180 -0
- package/build/agents/providers/pi/adapter.js +269 -0
- package/build/agents/providers/pi/checkpoint.js +41 -0
- package/build/agents/providers/pi/events.js +282 -0
- package/build/agents/{selector_v2.js → selector.js} +8 -6
- package/build/cli/commands/akuma/akuma/handler.js +4 -0
- package/build/cli/commands/akuma/akuma/meta.js +16 -0
- package/build/cli/commands/akuma/catalog.js +8 -0
- package/build/cli/commands/akuma/list/handler.js +15 -0
- package/build/cli/commands/akuma/list/meta-ls.js +9 -0
- package/build/cli/commands/akuma/view/handler.js +34 -0
- package/build/cli/commands/akuma/view/meta.js +8 -0
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +10 -0
- package/build/cli/commands/contract/amend/meta.js +12 -0
- package/build/cli/commands/contract/arc/handler.js +9 -0
- package/build/cli/commands/contract/arc/meta.js +26 -0
- package/build/cli/commands/contract/bind/handler.js +23 -0
- package/build/cli/commands/contract/bind/meta.js +30 -0
- package/build/cli/commands/contract/catalog.js +16 -0
- package/build/cli/commands/contract/forfeit/handler.js +13 -0
- package/build/cli/commands/contract/forfeit/meta.js +12 -0
- package/build/cli/commands/contract/log/handler.js +12 -0
- package/build/cli/commands/contract/log/meta.js +12 -0
- package/build/cli/commands/contract/petition/handler.js +26 -0
- package/build/cli/commands/contract/petition/meta.js +23 -0
- package/build/cli/commands/contract/renew/handler.js +10 -0
- package/build/cli/commands/contract/renew/meta.js +17 -0
- package/build/cli/commands/projection/call/handler.js +42 -0
- package/build/cli/commands/projection/call/meta.js +9 -0
- package/build/cli/commands/projection/catalog.js +14 -0
- package/build/cli/commands/projection/kill/handler.js +37 -0
- package/build/cli/commands/projection/kill/meta.js +11 -0
- package/build/cli/commands/projection/revive/handler.js +56 -0
- package/build/cli/commands/projection/revive/meta.js +9 -0
- package/build/cli/commands/projection/status/handler.js +25 -0
- package/build/cli/commands/projection/status/meta.js +9 -0
- package/build/cli/commands/projection/tell/handler.js +36 -0
- package/build/cli/commands/projection/tell/meta.js +9 -0
- package/build/cli/commands/projection/wait/handler.js +23 -0
- package/build/cli/commands/projection/wait/meta.js +11 -0
- package/build/cli/commands/registry.js +100 -0
- package/build/cli/commands/shared.js +71 -0
- package/build/cli/commands/skills/catalog.js +6 -0
- package/build/cli/commands/skills/install/handler.js +10 -0
- package/build/cli/commands/skills/install/meta.js +9 -0
- package/build/cli/commands/skills/skills/handler.js +4 -0
- package/build/cli/commands/skills/skills/meta.js +10 -0
- package/build/cli/commands/system/catalog.js +8 -0
- package/build/cli/commands/system/completion/handler.js +10 -0
- package/build/cli/commands/system/completion/meta.js +9 -0
- package/build/cli/commands/system/dump-env/handler.js +3 -0
- package/build/cli/commands/system/dump-env/meta.js +10 -0
- package/build/cli/commands/system/guide/handler.js +4 -0
- package/build/cli/commands/system/guide/meta.js +9 -0
- package/build/cli/commands/task/add/handler.js +21 -0
- package/build/cli/commands/task/add/meta.js +8 -0
- package/build/cli/commands/task/catalog.js +22 -0
- package/build/cli/commands/task/doctor/handler.js +4 -0
- package/build/cli/commands/task/doctor/meta.js +8 -0
- package/build/cli/commands/task/done/handler.js +17 -0
- package/build/cli/commands/task/done/meta.js +8 -0
- package/build/cli/commands/task/drop/handler.js +6 -0
- package/build/cli/commands/task/drop/meta.js +8 -0
- package/build/cli/commands/task/ls/handler.js +13 -0
- package/build/cli/commands/task/ls/meta.js +8 -0
- package/build/cli/commands/task/shared.js +131 -0
- package/build/cli/commands/task/start/handler.js +6 -0
- package/build/cli/commands/task/start/meta.js +8 -0
- package/build/cli/commands/task/stop/handler.js +17 -0
- package/build/cli/commands/task/stop/meta.js +8 -0
- package/build/cli/commands/task/task/handler.js +5 -0
- package/build/cli/commands/task/task/meta.js +11 -0
- package/build/cli/commands/task/update/handler.js +18 -0
- package/build/cli/commands/task/update/meta.js +8 -0
- package/build/cli/commands/task/view/handler.js +14 -0
- package/build/cli/commands/task/view/meta.js +8 -0
- package/build/cli/completion.js +26 -27
- package/build/cli/flags.js +79 -2
- package/build/cli/help.js +27 -49
- package/build/cli/index.js +121 -374
- package/build/cli/output-stream-error-policy.js +17 -0
- package/build/cli/parse-flags.js +197 -0
- package/build/cli/parse-metadata.js +129 -0
- package/build/cli/parse-selectors.js +65 -0
- package/build/cli/parse.js +46 -313
- package/build/cli/projection-address.js +5 -0
- package/build/cli/render/arc.js +1 -1
- package/build/cli/render/errors.js +4 -3
- package/build/cli/render/format.js +14 -0
- package/build/cli/render/kanshi.js +106 -0
- package/build/cli/render/petition.js +24 -1
- package/build/cli/render/projection-activity.js +5 -1
- package/build/cli/render/shared.js +2 -2
- package/build/cli/render/status.js +79 -13
- package/build/cli/render/task.js +113 -0
- package/build/cli/render/wait.js +23 -3
- package/build/cli/types.js +1 -1
- package/build/config/{akuma-loader_v2.js → akuma-loader.js} +7 -4
- package/build/config/env.js +9 -4
- package/build/config/settings/disease.js +26 -0
- package/build/config/settings/knobs.js +8 -0
- package/build/config/settings/loader.js +244 -0
- package/build/config/settings/schema.js +276 -0
- package/build/core/addressing.js +1 -1
- package/build/core/amend.js +5 -8
- package/build/core/arc.js +7 -8
- package/build/core/bind-workspace.js +123 -0
- package/build/core/bind.js +75 -155
- package/build/core/call/call.js +229 -0
- package/build/core/call/context.js +251 -0
- package/build/core/call/execution.js +217 -0
- package/build/core/call/prompt.js +42 -0
- package/build/core/call/reference.js +24 -0
- package/build/core/call-persist.js +10 -3
- package/build/core/claim-delivery.js +247 -0
- package/build/core/claim.js +39 -277
- package/build/core/context.js +2 -1
- package/build/core/{render.js → contract-view.js} +12 -140
- package/build/core/draft.js +107 -9
- package/build/core/entry.js +9 -1
- package/build/core/execution-coordinate.js +4 -20
- package/build/core/execution-pact.js +16 -31
- package/build/core/forfeit.js +35 -22
- package/build/core/hints.js +2 -2
- package/build/core/log.js +2 -2
- package/build/core/path-coordinate.js +27 -0
- package/build/core/petition-claim-gates.js +8 -6
- package/build/core/petition-preview.js +97 -0
- package/build/core/petition-run.js +5 -7
- package/build/core/petition.js +39 -26
- package/build/core/projection/generation/database.js +306 -0
- package/build/core/projection/generation/identity.js +84 -0
- package/build/core/projection/generation/model.js +201 -0
- package/build/core/projection/generation/store.js +73 -0
- package/build/core/projection/generation/transitions.js +258 -0
- package/build/core/projection/heart.js +0 -307
- package/build/core/projection/tell/database.js +109 -0
- package/build/core/projection/tell/model.js +97 -0
- package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
- package/build/core/projection-activity.js +23 -2
- package/build/core/projection-coordinate.js +14 -2
- package/build/core/projection-core.js +2 -1
- package/build/core/projection-execution-observer.js +259 -0
- package/build/core/projection-generation-continuation.js +1 -1
- package/build/core/projection-generation-execution.js +90 -20
- package/build/core/projection-generation-launcher.js +1 -1
- package/build/core/projection-generation-runner.js +198 -4
- package/build/core/projection-identity.js +1 -1
- package/build/core/projection-kill.js +50 -17
- package/build/core/projection-life-observer.js +1 -1
- package/build/core/projection-life-protocol.js +10 -0
- package/build/core/projection-mint.js +1 -1
- package/build/core/projection-status.js +45 -32
- package/build/core/projection-wait.js +12 -2
- package/build/core/projection-wake.js +5 -2
- package/build/core/{queue_v2.js → queue.js} +2 -1
- package/build/core/registry.js +1 -1
- package/build/core/renew.js +9 -11
- package/build/core/response-artifact-catalog-sqlite.js +112 -0
- package/build/core/response-artifact-catalog.js +7 -0
- package/build/core/seal.js +44 -16
- package/build/core/status/board.js +289 -0
- package/build/core/status/drift.js +99 -0
- package/build/core/status/lifecycle.js +84 -0
- package/build/core/status/reconciliation.js +131 -0
- package/build/core/stored-agent-event.js +28 -4
- package/build/core/target-ref.js +10 -0
- package/build/core/task/board.js +175 -0
- package/build/core/task/commands.js +211 -0
- package/build/core/task/document.js +189 -0
- package/build/core/task/model.js +1 -0
- package/build/core/task/settlement-git.js +207 -0
- package/build/core/task/settlement-policy.js +82 -0
- package/build/core/task/source-board.js +84 -0
- package/build/core/task/source-model.js +1 -0
- package/build/core/task/validation.js +44 -0
- package/build/core/task-contract.js +237 -0
- package/build/core/task-doctor.js +14 -0
- package/build/core/task-git-actor.js +38 -0
- package/build/core/task-git-runtime.js +37 -0
- package/build/core/task-git-store.js +385 -0
- package/build/core/task-repository.js +1 -0
- package/build/core/task-store-repository.js +86 -0
- package/build/core/task-store.js +1 -0
- package/build/core/task-worktree.js +51 -0
- package/build/core/task.js +4 -0
- package/build/core/transcripts.js +138 -56
- package/build/core/validation.js +17 -0
- package/build/core/verdict.js +2 -2
- package/build/core/worktree-path.js +33 -8
- package/build/flow-error.js +5 -2
- package/build/generated/version.js +1 -1
- package/build/git/branches.js +33 -9
- package/build/git/commits.js +3 -0
- package/build/git/core.js +9 -0
- package/build/git/diff/parsers.js +0 -94
- package/build/index.js +2 -0
- package/build/keiyaku-constants.js +2 -0
- package/build/keiyaku.js +4 -3
- package/package.json +3 -2
- package/skills/keiyaku/SKILL.md +30 -13
- package/skills/keiyaku-akuma/SKILL.md +30 -57
- package/skills/keiyaku-task/SKILL.md +51 -0
- package/skills/keiyaku-workflow/SKILL.md +71 -0
- package/build/agents/harness/pump.js +0 -158
- package/build/agents/providers/codex-app-server.js +0 -864
- package/build/agents/providers/opencode-sdk.js +0 -363
- package/build/agents/providers/pi.js +0 -557
- package/build/config/settings.js +0 -533
- package/build/core/call.js +0 -686
- package/build/core/projection/generation.js +0 -412
- package/build/core/projection/identity.js +0 -81
- package/build/core/projection/mint.js +0 -174
- package/build/core/projection-generation-store.js +0 -707
- package/build/core/status.js +0 -539
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/keiyaku",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.1",
|
|
4
4
|
"description": "CLI for running iterative keiyaku workflows with Codex subagents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -51,8 +51,9 @@
|
|
|
51
51
|
"@earendil-works/pi-coding-agent": "^0.80.10",
|
|
52
52
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
53
53
|
"@openai/codex-sdk": "^0.113.0",
|
|
54
|
-
"@opencode-ai/sdk": "1.
|
|
54
|
+
"@opencode-ai/sdk": "1.18.3",
|
|
55
55
|
"simple-git": "^3.21.0",
|
|
56
|
+
"yaml": "^2.9.0",
|
|
56
57
|
"zod": "4.3.6"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
package/skills/keiyaku/SKILL.md
CHANGED
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when working in a Keiyaku repository — contract-style coding where changes run on isolated branches and nothing lands without your sign-off.
|
|
4
4
|
allowed-tools: Bash(keiyaku *)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Keiyaku
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
CLI for contract-style coding in git repos. The mind model, Chainsaw Man rules: you make a **contract** to get work done, you can **call a devil** (akuma) to do it, and words mean nothing — only the commits left behind count. Nothing merges to main without your sign-off.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Mind model
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
keiyaku guide
|
|
15
|
-
keiyaku <command> --help
|
|
16
|
-
```
|
|
13
|
+
Three kinds of objects:
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
- **task** — a planning note in the repo. No branch, no execution. → `keiyaku-task` skill
|
|
16
|
+
- **contract** — a unit of work with its own branch + worktree. Born by `bind`, dies by `claim` (merged) or `forfeit` (abandoned). Who works inside it — you, an akuma, anyone — is not keiyaku's business; only the result is. → `keiyaku-workflow` skill
|
|
17
|
+
- **akuma / projection** — a callable worker and its live run. `call` starts one, `wait` watches it, `tell` sends more instructions. → `keiyaku-akuma` skill
|
|
19
18
|
|
|
20
|
-
##
|
|
19
|
+
## Quick start
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
```bash
|
|
22
|
+
keiyaku task add "fix the flaky pump test" # write the idea down → k-3f9a21c4b0d2
|
|
23
|
+
keiyaku bind --task k-3f9a21c4b0d2 # start it: branch + worktree
|
|
24
|
+
cd .keiyaku/wt/<place> # work and commit here — yourself,
|
|
25
|
+
# or: keiyaku call <akuma> "fix it"
|
|
26
|
+
keiyaku status # is anything stuck? what's next?
|
|
27
|
+
keiyaku petition <<'EOF' # done: seal + settle; the oath is required
|
|
28
|
+
## Oath
|
|
29
|
+
I fixed the flaky test; suite is green.
|
|
30
|
+
EOF
|
|
31
|
+
# passes → merged to main; a gate fails → keep working, petition again
|
|
32
|
+
```
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
That's the whole loop. Skip the task when the work needs no planning:
|
|
35
|
+
`keiyaku bind --place NAME --objective TEXT --scope GLOB --checks CHECK` (or the same as Markdown on stdin — `bind --help` shows the shape).
|
|
25
36
|
|
|
26
|
-
##
|
|
37
|
+
## Getting oriented
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
keiyaku status # the whole board: contracts, running work, ready tasks
|
|
41
|
+
keiyaku guide # long-form mechanics
|
|
42
|
+
keiyaku <command> --help # exact syntax — never guess flags or stdin formats
|
|
43
|
+
```
|
|
27
44
|
|
|
28
|
-
|
|
45
|
+
`status` is where you go when you lose track of anything: projection ids, contract state, what's ready.
|
|
@@ -1,75 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-akuma
|
|
3
|
-
description: Use when you need
|
|
3
|
+
description: Use when you need an Akuma to work for you — call a devil, watch it, send more instructions, kill it, or revive it from its record.
|
|
4
4
|
allowed-tools: Bash(keiyaku *)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Keiyaku Akuma
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
keiyaku akuma list
|
|
11
|
-
keiyaku <command> --help
|
|
12
|
-
```
|
|
9
|
+
Running devils. Contract lifecycle = `keiyaku-workflow` skill.
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
## Mind model
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
- **profile** — a devil you can call (`keiyaku akuma ls`). Markdown file: frontmatter = provider/model config, body = its instructions. Project `.keiyaku/akuma/` > user `~/.keiyaku/akuma/` > builtin.
|
|
14
|
+
- **projection** (`name/8hex`) — one live run of a devil. This is the id for `wait` / `tell` / `kill`.
|
|
15
|
+
- **artifact** (`rsp_…`) — what a finished run left behind. This is the id for `revive`.
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
| --- | --- | --- |
|
|
20
|
-
| projection id | live who | `wait`, `tell`, `status` |
|
|
21
|
-
| artifact id | saved answer | `revive` |
|
|
17
|
+
Rule of thumb: alive → projection id; want to continue a finished/dead one → artifact id.
|
|
22
18
|
|
|
23
|
-
##
|
|
19
|
+
## Common usage
|
|
24
20
|
|
|
25
21
|
```bash
|
|
26
|
-
keiyaku
|
|
27
|
-
keiyaku call NAME
|
|
28
|
-
keiyaku wait
|
|
29
|
-
keiyaku
|
|
30
|
-
keiyaku
|
|
31
|
-
keiyaku wait <
|
|
32
|
-
keiyaku
|
|
33
|
-
keiyaku
|
|
22
|
+
keiyaku akuma ls # who's callable
|
|
23
|
+
keiyaku call NAME "do the thing" # run in foreground until it finishes
|
|
24
|
+
keiyaku call NAME --wait 10m "do the thing" # bounded: after 10m you get a snapshot, it keeps running
|
|
25
|
+
keiyaku call NAME --detach "do the thing" # fire and forget; note the projection id
|
|
26
|
+
keiyaku call NAME - < prompt.md # long prompt: literal `-` reads stdin
|
|
27
|
+
keiyaku wait <proj-id> # join a running one; prints its activity
|
|
28
|
+
keiyaku wait <proj-id> --timeout 5m # peek for 5m; timeout = snapshot, not death
|
|
29
|
+
keiyaku tell <proj-id> "also do X" # drop instructions in its mailbox
|
|
30
|
+
keiyaku tell <proj-id> --wait 5m "also do X" # tell, then watch the response
|
|
31
|
+
keiyaku revive rsp_XXXX "continue..." # new run continuing from a record
|
|
32
|
+
keiyaku kill <proj-id> # stop it; record survives, revive still works
|
|
33
|
+
keiyaku status # forgot an id? it's on the board
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## Timeouts (do not confuse)
|
|
39
|
-
|
|
40
|
-
| Surface | Behavior |
|
|
41
|
-
| --- | --- |
|
|
42
|
-
| `call` / `revive` | **No** CLI `--timeout`. Foreground call joins until terminal or signal. |
|
|
43
|
-
| `call --detach` | Returns after launch. Bounded watching is done with `wait --timeout`. |
|
|
44
|
-
| `wait --timeout DURATION` | Only wait command. Forms: `45s`, `5m`, `2h` (max `24h`). Omit = wait until terminal. Timeout exit is a snapshot, not death. |
|
|
45
|
-
| Worker kill (env) | `KEIYAKU_SUBAGENT_EXEC_TIMEOUT_MS` (default 2700000), `KEIYAKU_SUBAGENT_EXEC_IDLE_TIMEOUT_MS` (default 600000). Not CLI flags. |
|
|
46
|
-
| Startup stall | Adoption timeout → wait/status can show `startup timed out` (launch never adopted). |
|
|
47
|
-
|
|
48
|
-
## Tell vs wait
|
|
49
|
-
|
|
50
|
-
- `tell` writes mailbox intent and may wake when eligible. It does **not** join.
|
|
51
|
-
- After tell: run `wait` (optionally `--timeout`) for outcome and activity.
|
|
52
|
-
- While pending tells exist, wait header can show `N tells waiting`.
|
|
53
|
-
|
|
54
|
-
## Activity list
|
|
55
|
-
|
|
56
|
-
No separate `activity` command.
|
|
57
|
-
|
|
58
|
-
- **`wait`**: full activity timeline (tools/turns) under the projection header.
|
|
59
|
-
- **`status`**: under `akuma` section, compact per-projection activity summary + tell counts.
|
|
60
|
-
|
|
61
|
-
Lost the outer handle → `status` to find projection id → `wait` for the list.
|
|
62
|
-
|
|
63
|
-
## Infrastructure
|
|
64
|
-
|
|
65
|
-
- `-C` / `--cwd DIR` — effective command directory (all akuma commands)
|
|
36
|
+
## Expectations
|
|
66
37
|
|
|
67
|
-
|
|
38
|
+
- `tell` is silent on success: exit 0, zero output. Silence **is** the receipt — do not re-send. Effects show up in `wait`/`status`.
|
|
39
|
+
- Body is required for `call`/`tell`. Piping stdin without a literal `-` does nothing.
|
|
40
|
+
- A `--wait`/`--timeout` expiry prints a live snapshot and exits 0 — the run continues; rejoin with `wait` anytime.
|
|
41
|
+
- `wait` is repeatable: on a finished run it shows the final transcript again.
|
|
42
|
+
- `--contract ADDR` attaches a call to a contract (by place, slug, or full id); `--bare` skips attachment explicitly. `call` only — `revive` takes neither.
|
|
68
43
|
|
|
69
|
-
|
|
70
|
-
- `--incognito` — no response artifact, no later revive (call only)
|
|
71
|
-
- `@addr` / `--contract` — attach commission/arc context when present (call, wait, tell)
|
|
72
|
-
- `--bare` — skip contract attachment only (call only)
|
|
73
|
-
- `--effort LEVEL` — override opaque provider-native effort value (call, revive, tell); must match profile allowlist when set
|
|
44
|
+
## Occasional flags
|
|
74
45
|
|
|
75
|
-
|
|
46
|
+
- `--incognito` — no artifact written, no revive possible (call)
|
|
47
|
+
- `--effort LEVEL` — provider effort override; needs a model set (call, revive, tell)
|
|
48
|
+
- `-C DIR` — run relative to another directory (all akuma commands)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: keiyaku-task
|
|
3
|
+
description: Use when planning work in a Keiyaku repo — add tasks, wire dependencies, track what's ready, promote a task into a contract.
|
|
4
|
+
allowed-tools: Bash(keiyaku *)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Keiyaku Task
|
|
8
|
+
|
|
9
|
+
Planning notes that live in the repo. Executing them is `keiyaku-workflow` (`bind --task`).
|
|
10
|
+
|
|
11
|
+
## Mind model
|
|
12
|
+
|
|
13
|
+
A task is a Markdown file in `.keiyaku/tasks/` — id `k-<12hex>`, priority 0–3 (0 highest, default 2), optional body. It has no branch and runs nothing; it's the queue you pull from. States:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
open ⇄ in_progress → done | drop
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Ready** = open + every `needs` dependency done. Ready is computed for you — `status` and `task ls` surface it.
|
|
20
|
+
|
|
21
|
+
## Common usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
keiyaku task add "fix the flaky pump test" # body: pipe stdin for details
|
|
25
|
+
keiyaku task add "title" --pri 1 --needs k-aaa # priority + dependency at birth
|
|
26
|
+
keiyaku task ls # all open, priority order
|
|
27
|
+
keiyaku task view k-xxxx # full detail incl. needs/blocks
|
|
28
|
+
keiyaku task start k-xxxx # mark in_progress (start ≠ execute)
|
|
29
|
+
keiyaku task stop k-xxxx # back to open
|
|
30
|
+
keiyaku task done k-xxxx
|
|
31
|
+
keiyaku task drop k-xxxx # won't do; kept in history, not deleted
|
|
32
|
+
keiyaku task update k-xxxx --pri 0 # also --title, --body TEXT|-, --needs,
|
|
33
|
+
# --drop-needs — see --help
|
|
34
|
+
keiyaku task doctor # check board integrity
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Dependencies
|
|
38
|
+
|
|
39
|
+
`--needs` stores the forward edge; `blocks` on the other task is derived automatically. Cycles are rejected at write time. Use needs to express "don't start B before A lands" — nothing more.
|
|
40
|
+
|
|
41
|
+
## Promoting to a contract
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
keiyaku bind --task k-xxxx
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Only a **ready** task binds. in_progress → `task stop` first; blocked → finish its needs first. Binding links the task to the contract; the contract's intent you still write yourself — the title doesn't auto-expand into a spec.
|
|
48
|
+
|
|
49
|
+
## Gotcha
|
|
50
|
+
|
|
51
|
+
Task files are ordinary tracked files: checking out another branch shows *that branch's* board. Don't panic when states differ across branches — you're reading a different branch's truth, and the old one is still in git.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: keiyaku-workflow
|
|
3
|
+
description: Use when driving a Keiyaku contract — bind to start isolated work, arc/renew mid-flight, petition for review, claim or forfeit to finish.
|
|
4
|
+
allowed-tools: Bash(keiyaku *)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Keiyaku Workflow
|
|
8
|
+
|
|
9
|
+
How a contract lives. Running akuma is the `keiyaku-akuma` skill; task planning is `keiyaku-task`.
|
|
10
|
+
|
|
11
|
+
## Mind model
|
|
12
|
+
|
|
13
|
+
A contract = one branch + one worktree + a ledger (its record file in the repo). You work inside the worktree however you like; keiyaku only judges the result at petition. States:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
bound → active → petitioned → claimed | forfeited
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## The default flow
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
keiyaku bind --place fix-pump --objective "make the pump test pass" \
|
|
23
|
+
--scope "src/pump/**" --checks "pump tests green"
|
|
24
|
+
# or the same four fields as Markdown: keiyaku bind < contract.md
|
|
25
|
+
# (# <name> / ## Objective / ## Scope / ## Checks)
|
|
26
|
+
# or promote a ready task: keiyaku bind --task k-xxxx
|
|
27
|
+
|
|
28
|
+
cd .keiyaku/wt/fix-pump # worktree lives at .keiyaku/wt/<place>; commit normally
|
|
29
|
+
|
|
30
|
+
keiyaku petition <<'EOF'
|
|
31
|
+
## Oath
|
|
32
|
+
I made the pump test pass; ran the suite, all green.
|
|
33
|
+
EOF
|
|
34
|
+
# petition seals your work and runs the settlement pipeline itself —
|
|
35
|
+
# passes → claimed (merged to main); a gate fails → fix, petition again.
|
|
36
|
+
# The oath is required (OATH_MISSING otherwise) and checked for presence, not content.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
That's the whole small case: bind → commit → petition.
|
|
40
|
+
|
|
41
|
+
## Mid-flight commands (use when needed, skip otherwise)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
keiyaku arc < arc.md # optional iteration boundary: seals the current intent, opens
|
|
45
|
+
# the next. Markdown: # <title> / ## Objective / ## Brief.
|
|
46
|
+
# Only needed when one contract has multiple distinct pushes.
|
|
47
|
+
keiyaku renew # main moved under you → rebase onto it. Refuses on conflict
|
|
48
|
+
# instead of guessing; resolve, then renew again.
|
|
49
|
+
keiyaku amend < amendment.md # scope/checks changed → update the paper before the code
|
|
50
|
+
keiyaku log # this contract's history
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Gotchas:
|
|
54
|
+
- Base drift blocks petition — if main moved, `renew` first; petition tells you.
|
|
55
|
+
- After an explicit `arc` seals, new loose commits need another `arc` before `renew`/`petition` accept them.
|
|
56
|
+
- Not in the worktree? Address a contract with `--contract ADDR` (place, slug, or full id) or the `keiyaku @addr <verb>` prefix.
|
|
57
|
+
|
|
58
|
+
## Ending it
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
keiyaku forfeit --reason "superseded by fix-pump-v2"
|
|
62
|
+
# abandon: worktree destroyed, history kept. Manual only — nothing auto-forfeits.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
There is no `claim` command: claiming is the tail of a passing petition.
|
|
66
|
+
|
|
67
|
+
## Reading status
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
keiyaku status # every contract row: state, place, what to do next
|
|
71
|
+
```
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { claimAllInbox, claimFencedTells, listTellIds, markTellSubmitted, markTellConsumed, readTellSubmitted, readTellOriginal, isTellCausallyConsumed, appendGenerationEvent, } from "../../core/projection-core.js";
|
|
2
|
-
import { prepareAgentEventForPersistence, } from "./execution-handle.js";
|
|
3
|
-
const OPERATOR_PROMPT_MARKER = "[Operator prompt]\n";
|
|
4
|
-
function frameTellBodies(projectionDirectory, tellIds) {
|
|
5
|
-
const originals = tellIds.map((tellId) => readTellOriginal(projectionDirectory, "inflight", tellId));
|
|
6
|
-
const frames = originals
|
|
7
|
-
.map((original, index) => `--- tell ${tellIds[index]} ---\n${original.text}`)
|
|
8
|
-
.join("\n\n");
|
|
9
|
-
const effort = originals.reduce((value, original) => original.effort ?? value, undefined);
|
|
10
|
-
return { frames, ...(effort ? { effort } : {}) };
|
|
11
|
-
}
|
|
12
|
-
function operatorBodyForContinuation(prompt, tellFrames, sessionContinuation) {
|
|
13
|
-
if (!sessionContinuation)
|
|
14
|
-
return `${prompt}\n\n${tellFrames}`;
|
|
15
|
-
const markerAt = prompt.indexOf(OPERATOR_PROMPT_MARKER);
|
|
16
|
-
if (markerAt >= 0) {
|
|
17
|
-
return `${prompt.slice(0, markerAt + OPERATOR_PROMPT_MARKER.length)}${tellFrames}`;
|
|
18
|
-
}
|
|
19
|
-
return tellFrames;
|
|
20
|
-
}
|
|
21
|
-
/** Tier-2 boundary snapshot. No tells leaves prompt byte-identical. */
|
|
22
|
-
export function snapshotReplayPrompt(projectionDirectory, prompt, tellFence, executionId, options = {}) {
|
|
23
|
-
const tellIds = claimFencedTells(projectionDirectory, tellFence, executionId);
|
|
24
|
-
if (tellIds.length === 0)
|
|
25
|
-
return { prompt, tellIds };
|
|
26
|
-
const { frames, effort } = frameTellBodies(projectionDirectory, tellIds);
|
|
27
|
-
const nextPrompt = operatorBodyForContinuation(prompt, frames, options.sessionContinuation === true);
|
|
28
|
-
return { prompt: nextPrompt, tellIds, ...(effort ? { effort } : {}) };
|
|
29
|
-
}
|
|
30
|
-
/** Tier-2 has no steer acknowledgement: actual driver start is its ordinal-zero submission point. */
|
|
31
|
-
export function markReplayStarted(projectionDirectory, executionId, tellIds) {
|
|
32
|
-
for (const tellId of tellIds) {
|
|
33
|
-
if (listTellIds(projectionDirectory, "inflight").includes(tellId)) {
|
|
34
|
-
markTellSubmitted(projectionDirectory, tellId, { executionId, fence: { kind: "ordinal", ordinal: 0 } });
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/** A successful replay terminal is checkpoint ordinal one; failures intentionally do not consume. */
|
|
39
|
-
export function markReplayCompleted(projectionDirectory, executionId) {
|
|
40
|
-
for (const tellId of listTellIds(projectionDirectory, "submitted")) {
|
|
41
|
-
const submitted = readTellSubmitted(projectionDirectory, tellId);
|
|
42
|
-
if (submitted.executionId === executionId && submitted.fence && isTellCausallyConsumed(submitted.fence, { kind: "ordinal", ordinal: 1 })) {
|
|
43
|
-
markTellConsumed(projectionDirectory, tellId);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Tier-2's only submission acknowledgement. A created driver is deliberately
|
|
49
|
-
* insufficient: observe the first provider event, or a successful completion
|
|
50
|
-
* from a provider that emitted no events.
|
|
51
|
-
*/
|
|
52
|
-
export function createReplayRunStartGate(projectionDirectory, executionId, tellIds) {
|
|
53
|
-
let started = false;
|
|
54
|
-
const start = () => {
|
|
55
|
-
if (started)
|
|
56
|
-
return;
|
|
57
|
-
markReplayStarted(projectionDirectory, executionId, tellIds);
|
|
58
|
-
started = true;
|
|
59
|
-
};
|
|
60
|
-
return { observeProviderEvent: start, observeSuccessfulCompletion: start };
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Supervisor pump: iterates handle.events, forwards to publicChannel,
|
|
64
|
-
* persists public events and checks the tell ledger at checkpoints.
|
|
65
|
-
*/
|
|
66
|
-
export async function pumpSupervisor(handle, projectionDirectory, executionId, publicChannel, callbacks = {}, dependencies = {}) {
|
|
67
|
-
let persistenceEnabled = true;
|
|
68
|
-
let persistenceDiagnosticQueued = false;
|
|
69
|
-
const pendingDiagnostics = [];
|
|
70
|
-
const appendEvent = dependencies.appendGenerationEvent ?? appendGenerationEvent;
|
|
71
|
-
const dispatch = (event, persist = true) => {
|
|
72
|
-
if (persist && persistenceEnabled) {
|
|
73
|
-
try {
|
|
74
|
-
appendEvent(projectionDirectory, executionId, prepareAgentEventForPersistence(event));
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
persistenceEnabled = false;
|
|
78
|
-
if (!persistenceDiagnosticQueued) {
|
|
79
|
-
persistenceDiagnosticQueued = true;
|
|
80
|
-
pendingDiagnostics.push({
|
|
81
|
-
text: `event persistence degraded: ${String(error)}`,
|
|
82
|
-
persist: false,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
publicChannel.push(event);
|
|
88
|
-
callbacks.onEvent?.(event);
|
|
89
|
-
};
|
|
90
|
-
try {
|
|
91
|
-
for await (const event of handle.events) {
|
|
92
|
-
dispatch(event);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
if (error instanceof Error && error.code === "PROJECTION_STATE_ERROR") {
|
|
97
|
-
const event = handle.mintEvent({
|
|
98
|
-
type: "fail",
|
|
99
|
-
code: "PROJECTION_STATE_ERROR",
|
|
100
|
-
message: error.message,
|
|
101
|
-
});
|
|
102
|
-
if (event)
|
|
103
|
-
dispatch(event);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
const event = handle.mintEvent({
|
|
107
|
-
type: "diagnostic",
|
|
108
|
-
text: `pump error: ${String(error)}`,
|
|
109
|
-
});
|
|
110
|
-
if (event)
|
|
111
|
-
dispatch(event);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
for (const pending of pendingDiagnostics) {
|
|
115
|
-
const event = handle.mintEvent({ type: "diagnostic", text: pending.text });
|
|
116
|
-
if (event)
|
|
117
|
-
dispatch(event, pending.persist);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Build an onSyncCheckpoint callback that claims all inbox tells
|
|
122
|
-
* and delivers them via the given SteerControl.
|
|
123
|
-
* Intended for use inside adapter start() calls as the onSyncCheckpoint callback.
|
|
124
|
-
*/
|
|
125
|
-
export function buildSyncCheckpointCallback(projectionDirectory, executionId) {
|
|
126
|
-
const submitting = new Set();
|
|
127
|
-
return (control, checkpoint) => {
|
|
128
|
-
claimAllInbox(projectionDirectory);
|
|
129
|
-
for (const tellId of listTellIds(projectionDirectory, "inflight")) {
|
|
130
|
-
if (submitting.has(tellId))
|
|
131
|
-
continue;
|
|
132
|
-
submitting.add(tellId);
|
|
133
|
-
const original = readTellOriginal(projectionDirectory, "inflight", tellId);
|
|
134
|
-
const originalText = original.text;
|
|
135
|
-
const tell = {
|
|
136
|
-
id: tellId,
|
|
137
|
-
text: `--- tell ${tellId} ---\n${originalText}`,
|
|
138
|
-
...(original.effort ? { effort: original.effort } : {}),
|
|
139
|
-
};
|
|
140
|
-
void control.enqueue(tell)
|
|
141
|
-
.then((ack) => {
|
|
142
|
-
if (!ack)
|
|
143
|
-
throw new Error("provider enqueue resolved without TellSubmitAck");
|
|
144
|
-
markTellSubmitted(projectionDirectory, tellId, { executionId, fence: ack.fence });
|
|
145
|
-
})
|
|
146
|
-
.catch(() => {
|
|
147
|
-
// Leave in inflight for the next checkpoint.
|
|
148
|
-
})
|
|
149
|
-
.finally(() => submitting.delete(tellId));
|
|
150
|
-
}
|
|
151
|
-
for (const tellId of listTellIds(projectionDirectory, "submitted")) {
|
|
152
|
-
const submitted = readTellSubmitted(projectionDirectory, tellId);
|
|
153
|
-
if (submitted.executionId === executionId && submitted.fence && isTellCausallyConsumed(submitted.fence, checkpoint.fence)) {
|
|
154
|
-
markTellConsumed(projectionDirectory, tellId);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
}
|