@astrosheep/keiyaku 4.6.7 → 4.6.9
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 +46 -16
- package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/opencode/index.js +1 -1
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/pi/keiyaku.ts +0 -5
- package/build/skills/keiyaku/SKILL.md +5 -6
- package/build/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/src/akuma/akuma-call.d.ts +2 -0
- package/build/src/akuma/akuma-call.js +8 -2
- package/build/src/akuma/akuma-instance.d.ts +14 -1
- package/build/src/akuma/akuma-instance.js +37 -7
- package/build/src/akuma/akuma-observe.d.ts +33 -8
- package/build/src/akuma/akuma-observe.js +89 -63
- package/build/src/akuma/akuma-owner.d.ts +14 -2
- package/build/src/akuma/akuma-owner.js +49 -35
- package/build/src/akuma/akuma-selection-execution.js +9 -1
- package/build/src/akuma/akuma-stream.d.ts +22 -0
- package/build/src/akuma/akuma-stream.js +116 -0
- package/build/src/akuma/akuma-wait.d.ts +1 -40
- package/build/src/akuma/akuma-wait.js +23 -84
- package/build/src/akuma/akuma.d.ts +52 -16
- package/build/src/akuma/akuma.js +10 -10
- package/build/src/akuma/allowed.d.ts +7 -12
- package/build/src/akuma/allowed.js +13 -4
- package/build/src/akuma/archetype.d.ts +7 -15
- package/build/src/akuma/archetype.js +36 -35
- package/build/src/akuma/body-supervisor.d.ts +5 -5
- package/build/src/akuma/body-supervisor.js +22 -20
- package/build/src/akuma/body.d.ts +5 -3
- package/build/src/akuma/body.js +57 -8
- package/build/src/akuma/call-request.d.ts +30 -32
- package/build/src/akuma/call-request.js +10 -3
- package/build/src/akuma/caller.d.ts +39 -0
- package/build/src/akuma/caller.js +36 -0
- package/build/src/akuma/dispatch-association.d.ts +0 -1
- package/build/src/akuma/dispatch-association.js +0 -3
- package/build/src/akuma/heart/activity-schema.d.ts +12 -0
- package/build/src/akuma/heart/activity-schema.js +6 -0
- package/build/src/akuma/heart/facts.d.ts +16 -12
- package/build/src/akuma/heart/facts.js +8 -0
- package/build/src/akuma/heart/index.d.ts +61 -9
- package/build/src/akuma/heart/index.js +89 -24
- package/build/src/akuma/heart/rows.d.ts +3 -3
- package/build/src/akuma/heart/rows.js +5 -3
- package/build/src/akuma/heart/soul.d.ts +10 -1
- package/build/src/akuma/heart/soul.js +34 -24
- package/build/src/akuma/heart/storage.d.ts +20 -0
- package/build/src/akuma/heart/storage.js +62 -3
- package/build/src/akuma/heart/timeline.d.ts +7 -0
- package/build/src/akuma/heart/timeline.js +10 -0
- package/build/src/akuma/identity.d.ts +0 -1
- package/build/src/akuma/identity.js +2 -5
- package/build/src/akuma/index.d.ts +6 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/nuke.js +6 -28
- package/build/src/akuma/projection.d.ts +25 -11
- package/build/src/akuma/projection.js +24 -7
- package/build/src/akuma/provider-recipe.d.ts +18 -6
- package/build/src/akuma/provider-recipe.js +24 -1
- package/build/src/akuma/provider.d.ts +31 -10
- package/build/src/akuma/provider.js +105 -14
- package/build/src/akuma/providers/acp/events.js +29 -19
- package/build/src/akuma/providers/acp/index.js +2 -3
- package/build/src/akuma/providers/claude/events.js +110 -69
- package/build/src/akuma/providers/claude/index.d.ts +2 -2
- package/build/src/akuma/providers/claude/index.js +4 -8
- package/build/src/akuma/providers/codex-app-server/events.js +17 -2
- package/build/src/akuma/providers/codex-app-server/index.js +17 -11
- package/build/src/akuma/providers/decode.d.ts +33 -0
- package/build/src/akuma/providers/decode.js +65 -0
- package/build/src/akuma/providers/execution-environment.d.ts +2 -1
- package/build/src/akuma/providers/execution-environment.js +3 -0
- package/build/src/akuma/providers/grok-build/index.js +16 -48
- package/build/src/akuma/providers/index.js +2 -0
- package/build/src/akuma/providers/lifecycle.d.ts +9 -0
- package/build/src/akuma/providers/lifecycle.js +10 -0
- package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
- package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
- package/build/src/akuma/providers/opencode-sdk/events.js +146 -296
- package/build/src/akuma/providers/opencode-sdk/index.js +270 -431
- package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
- package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
- package/build/src/akuma/providers/opencode-sdk/session.js +75 -84
- package/build/src/akuma/providers/paseo/events.d.ts +33 -0
- package/build/src/akuma/providers/paseo/events.js +204 -0
- package/build/src/akuma/providers/paseo/index.d.ts +9 -0
- package/build/src/akuma/providers/paseo/index.js +357 -0
- package/build/src/akuma/providers/pi/events.d.ts +2 -0
- package/build/src/akuma/providers/pi/events.js +36 -38
- package/build/src/akuma/providers/pi/index.js +21 -35
- package/build/src/akuma/publication.d.ts +2 -0
- package/build/src/akuma/publication.js +5 -0
- package/build/src/akuma/request-lifecycle.d.ts +4 -2
- package/build/src/akuma/request-lifecycle.js +27 -12
- package/build/src/akuma/request-rendezvous.js +38 -55
- package/build/src/akuma/request-serve.d.ts +1 -1
- package/build/src/akuma/request-serve.js +77 -113
- package/build/src/akuma/requests.d.ts +3 -1
- package/build/src/akuma/requests.js +32 -0
- package/build/src/akuma/selection-observation.d.ts +129 -53
- package/build/src/akuma/selection-observation.js +3 -9
- package/build/src/akuma/turn-drive.d.ts +3 -0
- package/build/src/akuma/turn-drive.js +28 -10
- package/build/src/akuma-body.js +12 -22
- package/build/src/cli/akuma-caller.d.ts +3 -0
- package/build/src/cli/akuma-caller.js +31 -0
- package/build/src/cli/commands/akuma-grammar.js +10 -16
- package/build/src/cli/commands/akuma.js +25 -55
- package/build/src/cli/commands/contract-grammar.d.ts +9 -7
- package/build/src/cli/commands/contract-grammar.js +40 -47
- package/build/src/cli/commands/contract-help.d.ts +17 -7
- package/build/src/cli/commands/contract-help.js +50 -11
- package/build/src/cli/commands/contract.js +34 -63
- package/build/src/cli/commands/debt-grammar.d.ts +19 -0
- package/build/src/cli/commands/debt-grammar.js +323 -0
- package/build/src/cli/commands/debt-query.d.ts +5 -0
- package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
- package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
- package/build/src/cli/commands/{task.js → debt.js} +87 -164
- package/build/src/cli/coordinates.d.ts +1 -1
- package/build/src/cli/coordinates.js +1 -1
- package/build/src/cli/parse.d.ts +5 -5
- package/build/src/cli/parse.js +17 -16
- package/build/src/cli/render/akuma-activity.d.ts +11 -83
- package/build/src/cli/render/akuma-activity.js +20 -382
- package/build/src/cli/render/catalog.d.ts +4 -7
- package/build/src/cli/render/catalog.js +5 -5
- package/build/src/cli/render/contract-history.js +3 -6
- package/build/src/cli/render/contract.js +17 -52
- package/build/src/cli/render/debt.d.ts +28 -0
- package/build/src/cli/render/{task.js → debt.js} +55 -133
- package/build/src/cli/render/kanshi.js +28 -28
- package/build/src/cli/render/marks.d.ts +5 -5
- package/build/src/cli/render/marks.js +4 -10
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/render/receipt.js +3 -10
- package/build/src/cli/runtime.d.ts +1 -1
- package/build/src/cli/runtime.js +14 -20
- package/build/src/cli/scan.d.ts +1 -1
- package/build/src/cli/selectors.d.ts +3 -6
- package/build/src/cli/selectors.js +22 -53
- package/build/src/cli/usage.d.ts +1 -1
- package/build/src/cli/usage.js +4 -4
- package/build/src/contract-worktree.js +3 -3
- package/build/src/debt/board.d.ts +160 -0
- package/build/src/{task → debt}/board.js +89 -89
- package/build/src/debt/catalog.d.ts +11 -0
- package/build/src/debt/catalog.js +59 -0
- package/build/src/{task → debt}/context.d.ts +1 -1
- package/build/src/{task → debt}/context.js +1 -1
- package/build/src/{task → debt}/created-observation.d.ts +6 -10
- package/build/src/{task → debt}/created-observation.js +7 -7
- package/build/src/debt/document.d.ts +37 -0
- package/build/src/{task → debt}/document.js +37 -37
- package/build/src/debt/identity.d.ts +21 -0
- package/build/src/{task → debt}/identity.js +35 -35
- package/build/src/debt/index.d.ts +111 -0
- package/build/src/debt/index.js +203 -0
- package/build/src/{task → debt}/input.d.ts +8 -8
- package/build/src/{task → debt}/input.js +21 -21
- package/build/src/debt/lifecycle-operations.d.ts +6 -0
- package/build/src/{task → debt}/lifecycle-operations.js +27 -31
- package/build/src/debt/mutation-result.d.ts +981 -0
- package/build/src/debt/mutation-result.js +109 -0
- package/build/src/debt/mutation.d.ts +424 -0
- package/build/src/debt/mutation.js +223 -0
- package/build/src/debt/operation-types.d.ts +71 -0
- package/build/src/debt/operations.d.ts +28 -0
- package/build/src/{task → debt}/operations.js +59 -60
- package/build/src/debt/query.d.ts +76 -0
- package/build/src/{task → debt}/query.js +55 -55
- package/build/src/{task → debt}/store.d.ts +13 -13
- package/build/src/{task → debt}/store.js +58 -49
- package/build/src/debt/view.d.ts +4 -0
- package/build/src/debt/view.js +7 -0
- package/build/src/dispatch/index.d.ts +3 -3
- package/build/src/dispatch/index.js +1 -2
- package/build/src/git/observe.d.ts +6 -2
- package/build/src/git/observe.js +6 -2
- package/build/src/identity/coordinates.d.ts +1 -1
- package/build/src/index.d.ts +17 -17
- package/build/src/index.js +11 -11
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/read.js +54 -39
- package/build/src/kanshi/report.d.ts +7 -7
- package/build/src/kanshi/select.js +4 -4
- package/build/src/library/address.js +2 -4
- package/build/src/library/akuma-creation.d.ts +5 -1
- package/build/src/library/akuma-creation.js +27 -47
- package/build/src/library/akumas.d.ts +7 -7
- package/build/src/library/akumas.js +13 -9
- package/build/src/library/bind.d.ts +17 -17
- package/build/src/library/bind.js +16 -12
- package/build/src/library/contract-address.d.ts +9 -0
- package/build/src/library/contract-address.js +71 -0
- package/build/src/library/contract-composition.d.ts +4 -7
- package/build/src/library/contract-composition.js +6 -18
- package/build/src/library/contract-creation.d.ts +3 -5
- package/build/src/library/contract-creation.js +24 -22
- package/build/src/library/contract-execution.js +21 -26
- package/build/src/library/contract-outcomes.d.ts +2 -14
- package/build/src/library/contract-outcomes.js +2 -13
- package/build/src/library/contract-types.d.ts +38 -4
- package/build/src/library/delivery.d.ts +0 -2
- package/build/src/library/delivery.js +2 -5
- package/build/src/library/input.d.ts +2 -2
- package/build/src/library/input.js +5 -5
- package/build/src/library/invocation.js +2 -2
- package/build/src/library/keiyaku.d.ts +0 -5
- package/build/src/library/keiyaku.js +6 -12
- package/build/src/library/nuke.js +3 -3
- package/build/src/library/outcome.d.ts +626 -625
- package/build/src/library/outcome.js +13 -3
- package/build/src/library/reconcile.js +8 -16
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/repo.d.ts +3 -2
- package/build/src/library/repo.js +10 -5
- package/build/src/library/selection.d.ts +5 -8
- package/build/src/library/selection.js +22 -73
- package/build/src/plugin/akuma-signals.d.ts +2 -0
- package/build/src/plugin/akuma-signals.js +4 -0
- package/build/src/plugin/public.d.ts +32 -2
- package/build/src/plugin/runtime.js +5 -3
- package/build/src/protocol/amend.js +3 -2
- package/build/src/protocol/attempt.js +3 -8
- package/build/src/protocol/bind.d.ts +2 -2
- package/build/src/protocol/bind.js +1 -1
- package/build/src/protocol/deliver.js +3 -3
- package/build/src/protocol/operations.d.ts +1 -3
- package/build/src/protocol/operations.js +0 -8
- package/build/src/protocol/outcome.d.ts +1 -2
- package/build/src/protocol/outcome.js +1 -13
- package/build/src/protocol/placement.js +3 -10
- package/build/src/protocol/read/status.js +31 -70
- package/build/src/protocol/reintegrate.js +3 -10
- package/build/src/protocol/review.js +3 -3
- package/build/src/protocol/run.d.ts +5 -1
- package/build/src/protocol/run.js +3 -3
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/fence.d.ts +3 -3
- package/build/src/settlement/fence.js +4 -4
- package/build/src/settlement/holder.d.ts +16 -16
- package/build/src/settlement/holder.js +69 -63
- package/build/src/settlement/settle.d.ts +5 -5
- package/build/src/settlement/settle.js +53 -53
- package/package.json +19 -9
- package/plugins/paseo/plugin/index.server.ts +17 -0
- package/plugins/paseo/plugin/paseo-plugin.json +4 -0
- package/plugins/paseo/plugin/server/attach.ts +52 -0
- package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
- package/plugins/paseo/plugin/server/message.ts +60 -0
- package/plugins/paseo/plugin/server/mirror.ts +193 -0
- package/plugins/paseo/plugin/server/model.ts +14 -0
- package/plugins/paseo/plugin/server/provider.ts +276 -0
- package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
- package/plugins/paseo/plugin/server/sdk.ts +289 -0
- package/plugins/paseo/plugin/server/stop.ts +26 -0
- package/plugins/paseo/plugin/server/transport.ts +35 -0
- package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
- package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
- package/plugins/paseo/plugin/tsconfig.json +6 -0
- package/plugins/pi/keiyaku.ts +57 -0
- package/skills/keiyaku/SKILL.md +43 -0
- package/skills/keiyaku-akuma/SKILL.md +130 -0
- package/skills/keiyaku-akuma/references/automation.md +269 -0
- package/skills/keiyaku-babysit/SKILL.md +65 -0
- package/skills/keiyaku-bind/SKILL.md +216 -0
- package/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/skills/keiyaku-debt/SKILL.md +91 -0
- package/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
- package/build/skills/keiyaku-task/SKILL.md +0 -104
- package/build/src/cli/commands/amend.d.ts +0 -12
- package/build/src/cli/commands/amend.js +0 -10
- package/build/src/cli/commands/bind.d.ts +0 -11
- package/build/src/cli/commands/bind.js +0 -23
- package/build/src/cli/commands/task-grammar.d.ts +0 -19
- package/build/src/cli/commands/task-grammar.js +0 -384
- package/build/src/cli/commands/task-query.d.ts +0 -5
- package/build/src/cli/render/task.d.ts +0 -41
- package/build/src/dispatch/association.d.ts +0 -1
- package/build/src/dispatch/association.js +0 -1
- package/build/src/task/board.d.ts +0 -168
- package/build/src/task/catalog.d.ts +0 -11
- package/build/src/task/catalog.js +0 -59
- package/build/src/task/compose-language.d.ts +0 -57
- package/build/src/task/compose-language.js +0 -364
- package/build/src/task/compose-parser.d.ts +0 -32
- package/build/src/task/compose-parser.js +0 -180
- package/build/src/task/compose.d.ts +0 -16
- package/build/src/task/compose.js +0 -189
- package/build/src/task/document.d.ts +0 -39
- package/build/src/task/identity.d.ts +0 -21
- package/build/src/task/index.d.ts +0 -138
- package/build/src/task/index.js +0 -269
- package/build/src/task/lifecycle-operations.d.ts +0 -6
- package/build/src/task/mutation-result.d.ts +0 -1726
- package/build/src/task/mutation-result.js +0 -198
- package/build/src/task/mutation.d.ts +0 -590
- package/build/src/task/mutation.js +0 -262
- package/build/src/task/operation-types.d.ts +0 -71
- package/build/src/task/operations.d.ts +0 -28
- package/build/src/task/query.d.ts +0 -76
- package/build/src/task/view.d.ts +0 -4
- package/build/src/task/view.js +0 -7
- /package/build/src/{task → debt}/operation-types.js +0 -0
|
@@ -4,20 +4,26 @@ import { contractId } from "../core/facts/types.js";
|
|
|
4
4
|
import { GIT_REF, updateGitTree, updateRefsAtomically, writeBlob, writeStateCommit } from "../git/repository.js";
|
|
5
5
|
import { confirmPrivateStatePublication } from "../git/private-state-seat.js";
|
|
6
6
|
import { withGitTargetedReadObservation, } from "../git/read-observation.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { parseDebtId } from "../debt/identity.js";
|
|
8
|
+
import { acquireDebtSettlementFence } from "./fence.js";
|
|
9
|
+
// The private persisted spelling predates the product rename. Keep its bytes
|
|
10
|
+
// and path stable so an existing held association still settles after upgrade.
|
|
9
11
|
const HOLDER_ROOT = "settlement/task-holders";
|
|
10
12
|
const HOLDER_PREFIX = `${HOLDER_ROOT}/`;
|
|
11
13
|
const HOLDER_SUFFIX = ".json";
|
|
12
|
-
export function
|
|
14
|
+
export function debtHolderObservationSelection() {
|
|
13
15
|
return { subtrees: [HOLDER_ROOT] };
|
|
14
16
|
}
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
+
function storedIdentity(debtId) {
|
|
18
|
+
return `task/${debtId.slice("debt/".length)}`;
|
|
19
|
+
}
|
|
20
|
+
function holderPath(debtId) {
|
|
21
|
+
const digest = createHash("sha256").update(storedIdentity(debtId)).digest("hex");
|
|
17
22
|
return `${HOLDER_PREFIX}${digest}${HOLDER_SUFFIX}`;
|
|
18
23
|
}
|
|
19
24
|
function canonicalBytes(holder) {
|
|
20
|
-
|
|
25
|
+
const { version, debtId, contractId, disposition } = holder;
|
|
26
|
+
return Buffer.from(`${JSON.stringify({ version, taskId: storedIdentity(debtId), contractId, disposition })}\n`);
|
|
21
27
|
}
|
|
22
28
|
function corruption(message, cause) {
|
|
23
29
|
throw new AuthorityCorruptionError(message, cause === undefined ? {} : { cause });
|
|
@@ -27,67 +33,67 @@ function decodeHolder(path, bytes) {
|
|
|
27
33
|
try {
|
|
28
34
|
const text = Buffer.from(bytes).toString("utf8");
|
|
29
35
|
if (!text.endsWith("\n") || text.slice(0, -1).includes("\n"))
|
|
30
|
-
corruption(`
|
|
36
|
+
corruption(`DebtHolder is not one canonical JSON line: ${path}`);
|
|
31
37
|
value = JSON.parse(text);
|
|
32
38
|
}
|
|
33
39
|
catch (error) {
|
|
34
40
|
if (error instanceof AuthorityCorruptionError)
|
|
35
41
|
throw error;
|
|
36
|
-
return corruption(`invalid
|
|
42
|
+
return corruption(`invalid DebtHolder JSON: ${path}`, error);
|
|
37
43
|
}
|
|
38
44
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
39
|
-
corruption(`
|
|
45
|
+
corruption(`DebtHolder must be an object: ${path}`);
|
|
40
46
|
const record = value;
|
|
41
47
|
const keys = Object.keys(record);
|
|
42
48
|
if (keys.length !== 4 || keys.some((key) => !["version", "taskId", "contractId", "disposition"].includes(key))) {
|
|
43
|
-
corruption(`
|
|
49
|
+
corruption(`DebtHolder has invalid fields: ${path}`);
|
|
44
50
|
}
|
|
45
51
|
if (record.version !== 1)
|
|
46
|
-
corruption(`
|
|
47
|
-
if (typeof record.taskId !== "string")
|
|
48
|
-
corruption(`
|
|
52
|
+
corruption(`DebtHolder version must be 1: ${path}`);
|
|
53
|
+
if (typeof record.taskId !== "string" || !record.taskId.startsWith("task/"))
|
|
54
|
+
corruption(`DebtHolder identity is invalid: ${path}`);
|
|
49
55
|
if (typeof record.contractId !== "string")
|
|
50
|
-
corruption(`
|
|
51
|
-
let
|
|
56
|
+
corruption(`DebtHolder contractId is invalid: ${path}`);
|
|
57
|
+
let debtId;
|
|
52
58
|
let owner;
|
|
53
59
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
debtId = `debt/${record.taskId.slice("task/".length)}`;
|
|
61
|
+
parseDebtId(debtId);
|
|
56
62
|
owner = contractId(record.contractId);
|
|
57
63
|
}
|
|
58
64
|
catch (error) {
|
|
59
|
-
return corruption(`
|
|
65
|
+
return corruption(`DebtHolder identity is invalid: ${path}`, error);
|
|
60
66
|
}
|
|
61
67
|
if (record.disposition !== "held" && record.disposition !== "released") {
|
|
62
|
-
corruption(`
|
|
68
|
+
corruption(`DebtHolder disposition is invalid: ${path}`);
|
|
63
69
|
}
|
|
64
|
-
const holder = { version: 1,
|
|
65
|
-
if (holderPath(
|
|
66
|
-
corruption(`
|
|
70
|
+
const holder = { version: 1, debtId, contractId: owner, disposition: record.disposition };
|
|
71
|
+
if (holderPath(debtId) !== path)
|
|
72
|
+
corruption(`DebtHolder path does not match debtId: ${path}`);
|
|
67
73
|
if (!Buffer.from(canonicalBytes(holder)).equals(Buffer.from(bytes)))
|
|
68
|
-
corruption(`
|
|
74
|
+
corruption(`DebtHolder bytes are not canonical: ${path}`);
|
|
69
75
|
return holder;
|
|
70
76
|
}
|
|
71
|
-
function
|
|
77
|
+
function projectDebtHolders(holders) {
|
|
72
78
|
const projection = new Map();
|
|
73
79
|
for (const holder of holders) {
|
|
74
80
|
if (projection.has(holder.contractId)) {
|
|
75
|
-
corruption(`Contract has multiple current
|
|
81
|
+
corruption(`Contract has multiple current DebtHolders: ${holder.contractId}`);
|
|
76
82
|
}
|
|
77
83
|
projection.set(holder.contractId, holder);
|
|
78
84
|
}
|
|
79
85
|
return projection;
|
|
80
86
|
}
|
|
81
87
|
function update(holder) {
|
|
82
|
-
return { path: holderPath(holder.
|
|
88
|
+
return { path: holderPath(holder.debtId), bytes: canonicalBytes(holder) };
|
|
83
89
|
}
|
|
84
|
-
export function
|
|
85
|
-
return update({ version: 1,
|
|
90
|
+
export function claimDebtHolder(debtId, owner) {
|
|
91
|
+
return update({ version: 1, debtId, contractId: owner, disposition: "held" });
|
|
86
92
|
}
|
|
87
93
|
function detail(error) {
|
|
88
94
|
return error instanceof Error ? error.message : String(error);
|
|
89
95
|
}
|
|
90
|
-
function
|
|
96
|
+
function finishDebtHolderAdmission(debtId, result, close) {
|
|
91
97
|
try {
|
|
92
98
|
close();
|
|
93
99
|
return { kind: "completed", result };
|
|
@@ -95,11 +101,11 @@ function finishTaskHolderAdmission(taskId, result, close) {
|
|
|
95
101
|
catch (error) {
|
|
96
102
|
if (result.kind !== "accepted")
|
|
97
103
|
throw error;
|
|
98
|
-
return { kind: "accepted-release-failed", result,
|
|
104
|
+
return { kind: "accepted-release-failed", result, debtId, diagnostic: detail(error) };
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
|
-
export async function
|
|
102
|
-
const held = await
|
|
107
|
+
export async function admitWithDebtHolderFence(repository, debtId, action) {
|
|
108
|
+
const held = await acquireDebtSettlementFence(repository, debtId);
|
|
103
109
|
let result;
|
|
104
110
|
try {
|
|
105
111
|
result = await action();
|
|
@@ -113,19 +119,19 @@ export async function admitWithTaskHolderFence(repository, taskId, action) {
|
|
|
113
119
|
}
|
|
114
120
|
throw error;
|
|
115
121
|
}
|
|
116
|
-
return
|
|
122
|
+
return finishDebtHolderAdmission(debtId, result, () => held.close());
|
|
117
123
|
}
|
|
118
|
-
export async function
|
|
119
|
-
const current = (await
|
|
124
|
+
export async function releaseDebtHolder(channel, observation, owner) {
|
|
125
|
+
const current = (await readDebtHolderProjectionFromDecision(channel, observation)).get(owner) ?? null;
|
|
120
126
|
return current === null || current.disposition !== "held" ? null : update({ ...current, disposition: "released" });
|
|
121
127
|
}
|
|
122
128
|
async function releasedHolderIsCurrent(repository, channel, owner, expected) {
|
|
123
|
-
const current = (await
|
|
129
|
+
const current = (await observeDebtHolderProjection(repository, channel)).get(owner) ?? null;
|
|
124
130
|
return current?.disposition === "released" && Buffer.from(canonicalBytes(current)).equals(expected);
|
|
125
131
|
}
|
|
126
132
|
/** Publish the released holder against the same frozen observation that decided the release. */
|
|
127
|
-
export async function
|
|
128
|
-
const release = await
|
|
133
|
+
export async function publishDebtHolderRelease(repository, channel, observation, owner, seat) {
|
|
134
|
+
const release = await releaseDebtHolder(channel, observation, owner);
|
|
129
135
|
if (release === null)
|
|
130
136
|
return { kind: "not-held" };
|
|
131
137
|
const tree = await updateGitTree(repository, observation.admission.snapshot.tree, new Map([[release.path, { oid: await writeBlob(repository, release.bytes) }]]));
|
|
@@ -133,7 +139,7 @@ export async function publishTaskHolderRelease(repository, channel, observation,
|
|
|
133
139
|
repository,
|
|
134
140
|
tree,
|
|
135
141
|
parent: observation.admission.snapshot.commit,
|
|
136
|
-
message: `release held
|
|
142
|
+
message: `release held Debt completion: ${owner}`,
|
|
137
143
|
});
|
|
138
144
|
const publication = await updateRefsAtomically(repository, [
|
|
139
145
|
{
|
|
@@ -154,10 +160,10 @@ export async function publishTaskHolderRelease(repository, channel, observation,
|
|
|
154
160
|
kind: "non-published",
|
|
155
161
|
diagnostic: publication.kind === "non-published"
|
|
156
162
|
? detail(publication.error)
|
|
157
|
-
: "
|
|
163
|
+
: "Debt holder release publication state is unknown",
|
|
158
164
|
};
|
|
159
165
|
}
|
|
160
|
-
export async function
|
|
166
|
+
export async function readDebtHolderProjectionFromDecision(channel, observation) {
|
|
161
167
|
const read = {
|
|
162
168
|
snapshot: observation.admission.snapshot,
|
|
163
169
|
readBlobs: async (oids) => {
|
|
@@ -168,29 +174,29 @@ export async function readTaskHolderProjectionFromDecision(channel, observation)
|
|
|
168
174
|
blobs.set(oid, object);
|
|
169
175
|
else {
|
|
170
176
|
if (object.type !== "blob")
|
|
171
|
-
corruption(`
|
|
177
|
+
corruption(`DebtHolder Git object is not a blob: ${oid}`);
|
|
172
178
|
blobs.set(oid, { kind: "present", bytes: object.bytes });
|
|
173
179
|
}
|
|
174
180
|
}
|
|
175
181
|
return blobs;
|
|
176
182
|
},
|
|
177
183
|
};
|
|
178
|
-
return
|
|
184
|
+
return projectDebtHolders(await readDebtHoldersAt(read));
|
|
179
185
|
}
|
|
180
|
-
function
|
|
181
|
-
return withGitTargetedReadObservation(repository, channel,
|
|
186
|
+
function observeDebtHolderProjection(repository, channel) {
|
|
187
|
+
return withGitTargetedReadObservation(repository, channel, debtHolderObservationSelection(), readDebtHolderProjectionAt);
|
|
182
188
|
}
|
|
183
|
-
async function
|
|
184
|
-
const holder = (await
|
|
185
|
-
return holder?.disposition === "held" ? holder.
|
|
189
|
+
async function heldDebtForContract(repository, channel, owner) {
|
|
190
|
+
const holder = (await observeDebtHolderProjection(repository, channel)).get(owner) ?? null;
|
|
191
|
+
return holder?.disposition === "held" ? holder.debtId : null;
|
|
186
192
|
}
|
|
187
|
-
export async function
|
|
188
|
-
const
|
|
189
|
-
return
|
|
193
|
+
export async function releaseDebtHolderWithFence(repository, channel, owner, action) {
|
|
194
|
+
const debtId = await heldDebtForContract(repository, channel, owner);
|
|
195
|
+
return debtId === null
|
|
190
196
|
? { kind: "completed", result: await action() }
|
|
191
|
-
:
|
|
197
|
+
: admitWithDebtHolderFence(repository, debtId, action);
|
|
192
198
|
}
|
|
193
|
-
export async function
|
|
199
|
+
export async function readDebtHoldersAt(observation) {
|
|
194
200
|
const entries = [...observation.snapshot.paths].filter(([path, entry]) => path.startsWith(HOLDER_PREFIX) && entry.type === "blob");
|
|
195
201
|
const blobs = await observation.readBlobs(entries.map(([, entry]) => entry.oid));
|
|
196
202
|
const holders = [];
|
|
@@ -198,26 +204,26 @@ export async function readTaskHoldersAt(observation) {
|
|
|
198
204
|
for (const [path, entry] of observation.snapshot.paths) {
|
|
199
205
|
if (path === HOLDER_ROOT) {
|
|
200
206
|
if (entry.type !== "tree")
|
|
201
|
-
corruption(`
|
|
207
|
+
corruption(`DebtHolder authority root is not a tree: ${path}`);
|
|
202
208
|
continue;
|
|
203
209
|
}
|
|
204
210
|
if (!path.startsWith(HOLDER_PREFIX))
|
|
205
211
|
continue;
|
|
206
212
|
if (!path.endsWith(HOLDER_SUFFIX))
|
|
207
|
-
corruption(`unexpected
|
|
213
|
+
corruption(`unexpected DebtHolder authority path: ${path}`);
|
|
208
214
|
if (entry.type !== "blob")
|
|
209
|
-
corruption(`
|
|
215
|
+
corruption(`DebtHolder path is not a blob: ${path}`);
|
|
210
216
|
const result = blobs.get(entry.oid);
|
|
211
217
|
if (result?.kind !== "present")
|
|
212
|
-
corruption(`missing
|
|
218
|
+
corruption(`missing DebtHolder Git object: ${path}`);
|
|
213
219
|
const holder = decodeHolder(path, result.bytes);
|
|
214
|
-
if (seen.has(holder.
|
|
215
|
-
corruption(`duplicate
|
|
216
|
-
seen.add(holder.
|
|
220
|
+
if (seen.has(holder.debtId))
|
|
221
|
+
corruption(`duplicate DebtHolder identity: ${holder.debtId}`);
|
|
222
|
+
seen.add(holder.debtId);
|
|
217
223
|
holders.push(holder);
|
|
218
224
|
}
|
|
219
|
-
return holders.sort((left, right) => Buffer.compare(Buffer.from(left.
|
|
225
|
+
return holders.sort((left, right) => Buffer.compare(Buffer.from(left.debtId), Buffer.from(right.debtId)));
|
|
220
226
|
}
|
|
221
|
-
export async function
|
|
222
|
-
return
|
|
227
|
+
export async function readDebtHolderProjectionAt(observation) {
|
|
228
|
+
return projectDebtHolders(await readDebtHoldersAt(observation));
|
|
223
229
|
}
|
|
@@ -5,19 +5,19 @@ import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
|
5
5
|
import type { Effect } from "../git/reconcile.js";
|
|
6
6
|
import { type GitRepository } from "../git/process.js";
|
|
7
7
|
export declare const settlementActionSchema: z.ZodObject<{
|
|
8
|
-
kind: z.ZodLiteral<"
|
|
9
|
-
|
|
8
|
+
kind: z.ZodLiteral<"debt">;
|
|
9
|
+
debtId: z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>;
|
|
10
10
|
action: z.ZodLiteral<"done">;
|
|
11
11
|
}, z.core.$strict>;
|
|
12
12
|
export type SettlementAction = z.infer<typeof settlementActionSchema>;
|
|
13
13
|
export declare const settlementLagSchema: z.ZodObject<{
|
|
14
14
|
kind: z.ZodLiteral<"settlement-failed">;
|
|
15
15
|
surface: z.ZodEnum<{
|
|
16
|
-
|
|
17
|
-
"
|
|
16
|
+
debt: "debt";
|
|
17
|
+
"debt-holder": "debt-holder";
|
|
18
18
|
}>;
|
|
19
19
|
contractId: z.ZodPipe<z.ZodString, z.ZodTransform<ContractId, string>>;
|
|
20
|
-
|
|
20
|
+
debtId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>>;
|
|
21
21
|
path: z.ZodOptional<z.ZodString>;
|
|
22
22
|
diagnostic: z.ZodString;
|
|
23
23
|
}, z.core.$strict>;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { contractIdSchema } from "../git/identity.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
3
|
+
import { debtIdSchema } from "../debt/identity.js";
|
|
4
4
|
import { observeContractsForAdmissionAt } from "../git/observe.js";
|
|
5
5
|
import { appendPrivateStateSeatClose, withPrivateStatePublicationSeat, } from "../git/private-state-seat.js";
|
|
6
6
|
import { GitPlumbingError } from "../git/process.js";
|
|
7
7
|
import { SqliteTransactionLockError } from "../coordination/sqlite-transaction-lock.js";
|
|
8
8
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { settleDebt } from "../debt/operations.js";
|
|
10
|
+
import { publishDebtHolderRelease, readDebtHolderProjectionFromDecision, debtHolderObservationSelection, } from "./holder.js";
|
|
11
|
+
import { acquireDebtSettlementFence } from "./fence.js";
|
|
12
12
|
import { World } from "../world.js";
|
|
13
13
|
export const settlementActionSchema = z
|
|
14
|
-
.object({ kind: z.literal("
|
|
14
|
+
.object({ kind: z.literal("debt"), debtId: debtIdSchema, action: z.literal("done") })
|
|
15
15
|
.strict();
|
|
16
16
|
export const settlementLagSchema = z
|
|
17
17
|
.object({
|
|
18
18
|
kind: z.literal("settlement-failed"),
|
|
19
|
-
surface: z.enum(["
|
|
19
|
+
surface: z.enum(["debt-holder", "debt"]),
|
|
20
20
|
contractId: contractIdSchema,
|
|
21
|
-
|
|
21
|
+
debtId: debtIdSchema.optional(),
|
|
22
22
|
path: z
|
|
23
23
|
.string()
|
|
24
24
|
.refine((value) => value.trim() !== "")
|
|
@@ -36,10 +36,10 @@ function operational(error) {
|
|
|
36
36
|
function diagnostic(error) {
|
|
37
37
|
return error instanceof Error ? error.message : String(error);
|
|
38
38
|
}
|
|
39
|
-
function
|
|
39
|
+
function debtFailure(result) {
|
|
40
40
|
return result.kind === "retry"
|
|
41
|
-
? `
|
|
42
|
-
: `
|
|
41
|
+
? `Debt settlement requires retry: ${result.reason}`
|
|
42
|
+
: `Debt settlement refused: ${JSON.stringify(result.refusal)}`;
|
|
43
43
|
}
|
|
44
44
|
function recordLag(input, lag) {
|
|
45
45
|
input.lags.push(lag);
|
|
@@ -53,11 +53,11 @@ async function observeApplicableHolder(input) {
|
|
|
53
53
|
const { repository, channel, candidate } = input;
|
|
54
54
|
let observation;
|
|
55
55
|
try {
|
|
56
|
-
observation = await observeContractsForAdmissionAt(repository, channel, [candidate.id],
|
|
56
|
+
observation = await observeContractsForAdmissionAt(repository, channel, [candidate.id], debtHolderObservationSelection());
|
|
57
57
|
const state = observation.journals.get(candidate.id)?.state ?? null;
|
|
58
58
|
if (state === null || state.terminal?.kind !== "claimed")
|
|
59
59
|
return null;
|
|
60
|
-
const holder = (await
|
|
60
|
+
const holder = (await readDebtHolderProjectionFromDecision(channel, observation)).get(candidate.id) ?? null;
|
|
61
61
|
return holder?.disposition === "held" ? holder : null;
|
|
62
62
|
}
|
|
63
63
|
catch (error) {
|
|
@@ -65,15 +65,15 @@ async function observeApplicableHolder(input) {
|
|
|
65
65
|
throw error;
|
|
66
66
|
recordLag(input, {
|
|
67
67
|
kind: "settlement-failed",
|
|
68
|
-
surface: "
|
|
68
|
+
surface: "debt-holder",
|
|
69
69
|
contractId: candidate.id,
|
|
70
70
|
diagnostic: diagnostic(error),
|
|
71
71
|
});
|
|
72
72
|
return null;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
async function
|
|
76
|
-
const { repository, candidate,
|
|
75
|
+
async function completeHeldDebt(input) {
|
|
76
|
+
const { repository, candidate, debtId } = input;
|
|
77
77
|
let world;
|
|
78
78
|
try {
|
|
79
79
|
world = await World.at(repository.primaryWorktree);
|
|
@@ -83,38 +83,38 @@ async function completeHeldTask(input) {
|
|
|
83
83
|
throw error;
|
|
84
84
|
recordLag(input, {
|
|
85
85
|
kind: "settlement-failed",
|
|
86
|
-
surface: "
|
|
86
|
+
surface: "debt",
|
|
87
87
|
contractId: candidate.id,
|
|
88
|
-
|
|
88
|
+
debtId,
|
|
89
89
|
diagnostic: diagnostic(error),
|
|
90
90
|
});
|
|
91
91
|
return false;
|
|
92
92
|
}
|
|
93
93
|
let result;
|
|
94
94
|
try {
|
|
95
|
-
result = await
|
|
95
|
+
result = await settleDebt(world, debtId);
|
|
96
96
|
}
|
|
97
97
|
catch (error) {
|
|
98
98
|
if (!operational(error))
|
|
99
99
|
throw error;
|
|
100
100
|
recordLag(input, {
|
|
101
101
|
kind: "settlement-failed",
|
|
102
|
-
surface: "
|
|
102
|
+
surface: "debt",
|
|
103
103
|
contractId: candidate.id,
|
|
104
|
-
|
|
104
|
+
debtId,
|
|
105
105
|
diagnostic: diagnostic(error),
|
|
106
106
|
});
|
|
107
107
|
return false;
|
|
108
108
|
}
|
|
109
109
|
if (result.kind === "changed")
|
|
110
|
-
recordAction(input, { kind: "
|
|
110
|
+
recordAction(input, { kind: "debt", debtId, action: "done" });
|
|
111
111
|
if (result.kind === "changed" && result.cleanup !== undefined) {
|
|
112
112
|
for (const detail of result.cleanup.diagnostics) {
|
|
113
113
|
recordLag(input, {
|
|
114
114
|
kind: "settlement-failed",
|
|
115
|
-
surface: "
|
|
115
|
+
surface: "debt",
|
|
116
116
|
contractId: candidate.id,
|
|
117
|
-
|
|
117
|
+
debtId,
|
|
118
118
|
diagnostic: detail,
|
|
119
119
|
});
|
|
120
120
|
}
|
|
@@ -123,32 +123,32 @@ async function completeHeldTask(input) {
|
|
|
123
123
|
return true;
|
|
124
124
|
recordLag(input, {
|
|
125
125
|
kind: "settlement-failed",
|
|
126
|
-
surface: "
|
|
126
|
+
surface: "debt",
|
|
127
127
|
contractId: candidate.id,
|
|
128
|
-
|
|
129
|
-
diagnostic:
|
|
128
|
+
debtId,
|
|
129
|
+
diagnostic: debtFailure(result),
|
|
130
130
|
});
|
|
131
131
|
return false;
|
|
132
132
|
}
|
|
133
|
-
async function
|
|
134
|
-
const { repository, channel, candidate, seatClose,
|
|
133
|
+
async function releaseHeldDebtHolder(input) {
|
|
134
|
+
const { repository, channel, candidate, seatClose, debtId } = input;
|
|
135
135
|
try {
|
|
136
136
|
const outcome = await withPrivateStatePublicationSeat(repository, async (seat) => {
|
|
137
|
-
const observation = await observeContractsForAdmissionAt(repository, channel, [candidate.id],
|
|
137
|
+
const observation = await observeContractsForAdmissionAt(repository, channel, [candidate.id], debtHolderObservationSelection());
|
|
138
138
|
const state = observation.journals.get(candidate.id)?.state ?? null;
|
|
139
139
|
if (state === null || state.terminal?.kind !== "claimed")
|
|
140
140
|
return "inert";
|
|
141
|
-
const holder = (await
|
|
142
|
-
if (holder === null || holder.disposition !== "held" || holder.
|
|
141
|
+
const holder = (await readDebtHolderProjectionFromDecision(channel, observation)).get(candidate.id) ?? null;
|
|
142
|
+
if (holder === null || holder.disposition !== "held" || holder.debtId !== debtId)
|
|
143
143
|
return "inert";
|
|
144
|
-
const publication = await
|
|
144
|
+
const publication = await publishDebtHolderRelease(repository, channel, observation, candidate.id, seat);
|
|
145
145
|
if (publication.kind === "non-published") {
|
|
146
146
|
recordLag(input, {
|
|
147
147
|
kind: "settlement-failed",
|
|
148
|
-
surface: "
|
|
148
|
+
surface: "debt-holder",
|
|
149
149
|
contractId: candidate.id,
|
|
150
|
-
|
|
151
|
-
diagnostic: `
|
|
150
|
+
debtId,
|
|
151
|
+
diagnostic: `Debt holder release requires retry: ${publication.diagnostic}`,
|
|
152
152
|
});
|
|
153
153
|
return "held";
|
|
154
154
|
}
|
|
@@ -165,51 +165,51 @@ async function releaseHeldTaskHolder(input) {
|
|
|
165
165
|
throw error;
|
|
166
166
|
recordLag(input, {
|
|
167
167
|
kind: "settlement-failed",
|
|
168
|
-
surface: "
|
|
168
|
+
surface: "debt-holder",
|
|
169
169
|
contractId: candidate.id,
|
|
170
|
-
|
|
170
|
+
debtId,
|
|
171
171
|
diagnostic: diagnostic(error),
|
|
172
172
|
});
|
|
173
173
|
return "held";
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
-
async function
|
|
176
|
+
async function settleDebts(input) {
|
|
177
177
|
const { repository, channel, candidate, lags, seatClose } = input;
|
|
178
178
|
const hint = await observeApplicableHolder(input);
|
|
179
179
|
if (hint === null)
|
|
180
180
|
return false;
|
|
181
|
-
const
|
|
181
|
+
const debtId = hint.debtId;
|
|
182
182
|
let fence;
|
|
183
183
|
try {
|
|
184
|
-
fence = await
|
|
184
|
+
fence = await acquireDebtSettlementFence(repository, debtId);
|
|
185
185
|
}
|
|
186
186
|
catch (error) {
|
|
187
187
|
if (!operational(error))
|
|
188
188
|
throw error;
|
|
189
189
|
recordLag(input, {
|
|
190
190
|
kind: "settlement-failed",
|
|
191
|
-
surface: "
|
|
191
|
+
surface: "debt",
|
|
192
192
|
contractId: candidate.id,
|
|
193
|
-
|
|
193
|
+
debtId,
|
|
194
194
|
diagnostic: diagnostic(error),
|
|
195
195
|
});
|
|
196
196
|
return true;
|
|
197
197
|
}
|
|
198
198
|
let failure;
|
|
199
|
-
let
|
|
199
|
+
let debtSettled = false;
|
|
200
200
|
let holderDisposition = null;
|
|
201
201
|
try {
|
|
202
202
|
const holder = await observeApplicableHolder(input);
|
|
203
|
-
if (holder === null || holder.
|
|
203
|
+
if (holder === null || holder.debtId !== debtId)
|
|
204
204
|
return false;
|
|
205
|
-
|
|
206
|
-
if (!
|
|
205
|
+
debtSettled = await completeHeldDebt({ ...input, debtId });
|
|
206
|
+
if (!debtSettled)
|
|
207
207
|
return true;
|
|
208
|
-
holderDisposition = await
|
|
208
|
+
holderDisposition = await releaseHeldDebtHolder({
|
|
209
209
|
repository,
|
|
210
210
|
channel,
|
|
211
211
|
candidate,
|
|
212
|
-
|
|
212
|
+
debtId,
|
|
213
213
|
lags,
|
|
214
214
|
seatClose,
|
|
215
215
|
...(input.progress === undefined ? {} : { progress: input.progress }),
|
|
@@ -229,15 +229,15 @@ async function settleTasks(input) {
|
|
|
229
229
|
if (failure === undefined)
|
|
230
230
|
throw error;
|
|
231
231
|
}
|
|
232
|
-
else if (!
|
|
232
|
+
else if (!debtSettled && failure === undefined)
|
|
233
233
|
throw error;
|
|
234
234
|
// Post-release fence teardown is custodial residue, not an owed holder publication.
|
|
235
235
|
if (holderDisposition !== "released") {
|
|
236
236
|
recordLag(input, {
|
|
237
237
|
kind: "settlement-failed",
|
|
238
|
-
surface: "
|
|
238
|
+
surface: "debt-holder",
|
|
239
239
|
contractId: candidate.id,
|
|
240
|
-
|
|
240
|
+
debtId,
|
|
241
241
|
diagnostic: diagnostic(error),
|
|
242
242
|
});
|
|
243
243
|
}
|
|
@@ -258,7 +258,7 @@ async function settleObserved(input) {
|
|
|
258
258
|
const candidate = input.state;
|
|
259
259
|
if (candidate.terminal?.kind === "claimed") {
|
|
260
260
|
try {
|
|
261
|
-
await
|
|
261
|
+
await settleDebts({
|
|
262
262
|
repository: input.repository,
|
|
263
263
|
channel: input.channel,
|
|
264
264
|
candidate,
|
|
@@ -273,7 +273,7 @@ async function settleObserved(input) {
|
|
|
273
273
|
throw error;
|
|
274
274
|
recordLag({ candidate, lags, ...(input.progress === undefined ? {} : { progress: input.progress }) }, {
|
|
275
275
|
kind: "settlement-failed",
|
|
276
|
-
surface: "
|
|
276
|
+
surface: "debt",
|
|
277
277
|
contractId: candidate.id,
|
|
278
278
|
diagnostic: diagnostic(error),
|
|
279
279
|
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/keiyaku",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.9",
|
|
4
4
|
"workspaces": [
|
|
5
|
-
"plugins/square"
|
|
5
|
+
"plugins/square",
|
|
6
|
+
"plugins/paseo/forwarder"
|
|
6
7
|
],
|
|
7
8
|
"files": [
|
|
8
|
-
"build"
|
|
9
|
+
"build",
|
|
10
|
+
"plugins/pi",
|
|
11
|
+
"plugins/paseo/plugin",
|
|
12
|
+
"skills"
|
|
9
13
|
],
|
|
10
14
|
"main": "./build/src/index.js",
|
|
11
15
|
"types": "./build/src/index.d.ts",
|
|
@@ -29,7 +33,7 @@
|
|
|
29
33
|
},
|
|
30
34
|
"scripts": {
|
|
31
35
|
"release": "npm run test:release && npm version patch && npm publish",
|
|
32
|
-
"build": "node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('build', { recursive: true, force: true })\" && tsc -p tsconfig.json && npm run build --workspace @astrosheep/keiyaku-plugin-square && node scripts/copy-plugins.js && node scripts/build-windows-launcher.js && node --input-type=module -e \"import { chmodSync } from 'node:fs'; chmodSync('build/src/cli/index.js', 0o755)\"",
|
|
36
|
+
"build": "node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('build', { recursive: true, force: true })\" && tsc -p tsconfig.json && npm run build --workspace @astrosheep/keiyaku-plugin-square && npm run build --workspace @astrosheep/keiyaku-plugin-paseo && node scripts/copy-plugins.js && node scripts/build-windows-launcher.js && node --input-type=module -e \"import { chmodSync } from 'node:fs'; chmodSync('build/src/cli/index.js', 0o755)\"",
|
|
33
37
|
"prepack": "node scripts/verify-package.js",
|
|
34
38
|
"postpack": "node scripts/verify-package.js",
|
|
35
39
|
"harness:version": "node scripts/update-harness-version.js",
|
|
@@ -61,8 +65,10 @@
|
|
|
61
65
|
},
|
|
62
66
|
"devDependencies": {
|
|
63
67
|
"@earendil-works/pi-coding-agent": "^1.0.0",
|
|
68
|
+
"@getpaseo/plugin": "0.11.2",
|
|
64
69
|
"@types/cross-spawn": "^6.0.6",
|
|
65
70
|
"@types/node": "^25.0.0",
|
|
71
|
+
"@types/ws": "^8.18.2",
|
|
66
72
|
"@typescript-eslint/parser": "^8.66.0",
|
|
67
73
|
"eslint": "^9.39.5",
|
|
68
74
|
"knip": "^6.31.0",
|
|
@@ -73,11 +79,15 @@
|
|
|
73
79
|
"dependencies": {
|
|
74
80
|
"@agentclientprotocol/sdk": "^1.3.0",
|
|
75
81
|
"@anthropic-ai/claude-agent-sdk": "^0.3.226",
|
|
76
|
-
"@astrosheep/keiyaku-plugin-
|
|
77
|
-
"@astrosheep/square": "
|
|
78
|
-
"@
|
|
82
|
+
"@astrosheep/keiyaku-plugin-paseo": "0.1.0",
|
|
83
|
+
"@astrosheep/keiyaku-plugin-square": "0.1.9",
|
|
84
|
+
"@astrosheep/square": "^0.3.79",
|
|
85
|
+
"@getpaseo/client": "0.11.2",
|
|
86
|
+
"@getpaseo/protocol": "0.11.2",
|
|
87
|
+
"@opencode/client": "2.0.20",
|
|
79
88
|
"cross-spawn": "^7.0.6",
|
|
80
89
|
"diff": "^8.0.4",
|
|
90
|
+
"undici": "8.10.2",
|
|
81
91
|
"yaml": "^2.9.0",
|
|
82
92
|
"zod": "^4.5.2"
|
|
83
93
|
},
|
|
@@ -91,10 +101,10 @@
|
|
|
91
101
|
],
|
|
92
102
|
"pi": {
|
|
93
103
|
"extensions": [
|
|
94
|
-
"./
|
|
104
|
+
"./plugins/pi/keiyaku.ts"
|
|
95
105
|
],
|
|
96
106
|
"skills": [
|
|
97
|
-
"./
|
|
107
|
+
"./skills"
|
|
98
108
|
]
|
|
99
109
|
},
|
|
100
110
|
"author": "",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PluginServerContext } from "@getpaseo/plugin/server";
|
|
2
|
+
import { createProvider } from "./server/provider.js";
|
|
3
|
+
import { createSdkTransport } from "./server/sdk.js";
|
|
4
|
+
import { attach } from "./server/attach.js";
|
|
5
|
+
import { attachRpc } from "./shared/attach-rpc.js";
|
|
6
|
+
import { refreshRpc } from "./shared/refresh-rpc.js";
|
|
7
|
+
|
|
8
|
+
export default function contribute(server: PluginServerContext) {
|
|
9
|
+
const transport = createSdkTransport();
|
|
10
|
+
const mirror = createProvider(transport);
|
|
11
|
+
server.registerProvider(mirror.provider);
|
|
12
|
+
server.handle(refreshRpc, (input) => mirror.refresh(input));
|
|
13
|
+
server.handle(attachRpc, (input, context) => attach(input, context, mirror.sync));
|
|
14
|
+
return async () => {
|
|
15
|
+
try { await mirror.close(); } finally { await transport.close(); }
|
|
16
|
+
};
|
|
17
|
+
}
|