@astrosheep/keiyaku 4.0.0 → 4.0.2
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 +133 -8
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +50 -33
- package/build/src/akuma/akuma.js +175 -127
- package/build/src/akuma/archetype.d.ts +14 -5
- package/build/src/akuma/archetype.js +85 -39
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +490 -183
- package/build/src/akuma/coordinate.d.ts +9 -0
- package/build/src/akuma/coordinate.js +22 -0
- package/build/src/akuma/heart/facts.d.ts +88 -45
- package/build/src/akuma/heart/facts.js +19 -8
- package/build/src/akuma/heart/index.d.ts +64 -55
- package/build/src/akuma/heart/index.js +172 -252
- package/build/src/akuma/heart/rows.d.ts +38 -83
- package/build/src/akuma/heart/rows.js +117 -155
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +61 -22
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +47 -0
- package/build/src/akuma/heart/storage.js +224 -0
- package/build/src/akuma/heart/tells.d.ts +12 -0
- package/build/src/akuma/heart/tells.js +79 -0
- package/build/src/akuma/heart/timeline.d.ts +15 -0
- package/build/src/akuma/heart/timeline.js +86 -0
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +10 -3
- package/build/src/akuma/index.js +7 -1
- package/build/src/akuma/projection.d.ts +176 -0
- package/build/src/akuma/projection.js +256 -0
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +67 -13
- package/build/src/akuma/provider.js +172 -105
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
- package/build/src/akuma/providers/claude/events.js +238 -0
- package/build/src/akuma/providers/claude/index.d.ts +47 -0
- package/build/src/akuma/providers/claude/index.js +279 -0
- package/build/src/akuma/providers/claude/input.d.ts +13 -0
- package/build/src/akuma/providers/claude/input.js +109 -0
- package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
- package/build/src/akuma/providers/codex-app-server/events.js +15 -12
- package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
- package/build/src/akuma/providers/codex-app-server/index.js +77 -33
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +35 -56
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
- package/build/src/akuma/providers/pi/events.d.ts +33 -0
- package/build/src/akuma/providers/pi/events.js +166 -0
- package/build/src/akuma/providers/pi/index.d.ts +11 -0
- package/build/src/akuma/providers/pi/index.js +191 -0
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -6
- package/build/src/akuma/requests.js +95 -65
- package/build/src/alias/index.d.ts +4 -3
- package/build/src/alias/index.js +12 -13
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/body/render.js +2 -1
- package/build/src/body/shape.js +7 -1
- package/build/src/body/verification.js +19 -4
- package/build/src/cli/accepted.d.ts +18 -12
- package/build/src/cli/accepted.js +73 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
- package/build/src/cli/commands/akuma-invoke.js +101 -52
- package/build/src/cli/commands/akuma.d.ts +27 -9
- package/build/src/cli/commands/akuma.js +151 -80
- package/build/src/cli/commands/contract.d.ts +155 -0
- package/build/src/cli/commands/contract.js +20 -0
- package/build/src/cli/commands/install.js +2 -0
- package/build/src/cli/commands/task-invoke.d.ts +19 -4
- package/build/src/cli/commands/task-invoke.js +65 -17
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +52 -14
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +9 -3
- package/build/src/cli/invoke.js +287 -108
- package/build/src/cli/main.js +54 -7
- package/build/src/cli/parse.d.ts +21 -117
- package/build/src/cli/parse.js +79 -84
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +4 -2
- package/build/src/cli/render/akuma-tool.js +35 -5
- package/build/src/cli/render/akuma.d.ts +3 -1
- package/build/src/cli/render/akuma.js +247 -212
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/catalog.d.ts +2 -0
- package/build/src/cli/render/catalog.js +16 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +200 -54
- package/build/src/cli/render/kanshi.js +272 -129
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -3
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +20 -0
- package/build/src/cli/render/terminal.js +121 -0
- package/build/src/cli/render/text.js +11 -3
- package/build/src/cli/result.d.ts +126 -19
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +44 -0
- package/build/src/contract-worktree.js +251 -0
- package/build/src/coordination/durable-file.d.ts +5 -1
- package/build/src/coordination/durable-file.js +57 -10
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/codec.js +23 -4
- package/build/src/core/facts/eligibility.d.ts +1 -10
- package/build/src/core/facts/eligibility.js +0 -49
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/facts/observation.d.ts +3 -0
- package/build/src/core/facts/observation.js +12 -0
- package/build/src/core/facts/types.d.ts +10 -3
- package/build/src/core/subject.js +2 -2
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +3 -18
- package/build/src/core/verbs/bind.js +2 -16
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +14 -4
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +7 -9
- package/build/src/dispatch/index.d.ts +5 -3
- package/build/src/dispatch/index.js +30 -21
- package/build/src/duration.d.ts +10 -0
- package/build/src/duration.js +22 -0
- package/build/src/git/admission.d.ts +2 -2
- package/build/src/git/admission.js +33 -23
- package/build/src/git/hooks.d.ts +15 -0
- package/build/src/git/hooks.js +70 -18
- package/build/src/git/identity.d.ts +5 -1
- package/build/src/git/identity.js +23 -4
- package/build/src/git/integration.d.ts +48 -0
- package/build/src/git/integration.js +250 -0
- package/build/src/git/observe.d.ts +29 -15
- package/build/src/git/observe.js +185 -76
- package/build/src/git/read-observation.d.ts +41 -0
- package/build/src/git/read-observation.js +361 -0
- package/build/src/git/reconcile.d.ts +17 -5
- package/build/src/git/reconcile.js +305 -109
- package/build/src/git/repository.d.ts +41 -18
- package/build/src/git/repository.js +220 -114
- package/build/src/git/scratch.d.ts +17 -0
- package/build/src/git/scratch.js +73 -0
- package/build/src/git/target-placement.d.ts +92 -0
- package/build/src/git/target-placement.js +375 -0
- package/build/src/git/tender.d.ts +49 -0
- package/build/src/git/tender.js +63 -0
- package/build/src/git/terminal-seal.d.ts +24 -0
- package/build/src/git/terminal-seal.js +89 -0
- package/build/src/git/tree.d.ts +2 -2
- package/build/src/git/tree.js +4 -0
- package/build/src/git/workspace.d.ts +53 -0
- package/build/src/git/workspace.js +139 -0
- package/build/src/identity/selector.d.ts +6 -0
- package/build/src/identity/selector.js +19 -0
- package/build/src/index.d.ts +4 -2
- package/build/src/index.js +2 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +7 -3
- package/build/src/kanshi/read.js +245 -45
- package/build/src/kanshi/report.d.ts +81 -6
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +33 -1
- package/build/src/library/address.d.ts +57 -0
- package/build/src/library/address.js +165 -0
- package/build/src/library/akuma-creation.d.ts +16 -7
- package/build/src/library/akuma-creation.js +96 -22
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.d.ts +21 -0
- package/build/src/library/bind.js +56 -0
- package/build/src/library/catalog.d.ts +58 -0
- package/build/src/library/catalog.js +69 -0
- package/build/src/library/configuration.d.ts +6 -15
- package/build/src/library/configuration.js +14 -17
- package/build/src/library/contract.d.ts +23 -49
- package/build/src/library/contract.js +171 -185
- package/build/src/library/delivery.d.ts +24 -0
- package/build/src/library/delivery.js +21 -0
- package/build/src/library/fleet.d.ts +65 -0
- package/build/src/library/fleet.js +153 -0
- package/build/src/library/input.d.ts +3 -0
- package/build/src/library/input.js +19 -0
- package/build/src/library/keiyaku.d.ts +18 -3
- package/build/src/library/keiyaku.js +12 -1
- package/build/src/library/mutation.d.ts +39 -0
- package/build/src/library/mutation.js +37 -0
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/refusal.d.ts +21 -0
- package/build/src/library/refusal.js +29 -0
- package/build/src/library/region.d.ts +14 -1
- package/build/src/library/region.js +18 -4
- package/build/src/library/repo.d.ts +4 -13
- package/build/src/library/repo.js +14 -24
- package/build/src/protocol/attempt.d.ts +16 -3
- package/build/src/protocol/attempt.js +41 -10
- package/build/src/protocol/bind.d.ts +9 -2
- package/build/src/protocol/bind.js +48 -40
- package/build/src/protocol/intent.d.ts +57 -20
- package/build/src/protocol/intent.js +55 -79
- package/build/src/protocol/operations.d.ts +152 -43
- package/build/src/protocol/operations.js +482 -166
- package/build/src/protocol/outcome.d.ts +14 -3
- package/build/src/protocol/outcome.js +11 -3
- package/build/src/protocol/placement.d.ts +41 -0
- package/build/src/protocol/placement.js +147 -0
- package/build/src/protocol/read/documents.d.ts +2 -2
- package/build/src/protocol/read/documents.js +4 -4
- package/build/src/protocol/read/status.d.ts +18 -5
- package/build/src/protocol/read/status.js +73 -13
- package/build/src/protocol/run.d.ts +49 -7
- package/build/src/protocol/run.js +53 -25
- package/build/src/runtime/proc/line-rpc.d.ts +4 -8
- package/build/src/runtime/proc/line-rpc.js +22 -28
- package/build/src/runtime/proc/run.d.ts +23 -21
- package/build/src/runtime/proc/run.js +123 -89
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +7 -1
- package/build/src/settings.js +32 -17
- package/build/src/settlement/fence.d.ts +5 -0
- package/build/src/settlement/fence.js +14 -0
- package/build/src/settlement/holder.d.ts +35 -4
- package/build/src/settlement/holder.js +127 -28
- package/build/src/settlement/settle.d.ts +9 -1
- package/build/src/settlement/settle.js +74 -37
- package/build/src/task/board.d.ts +23 -5
- package/build/src/task/board.js +17 -10
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +15 -20
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +27 -15
- package/build/src/task/index.js +57 -35
- package/build/src/task/operations.d.ts +38 -13
- package/build/src/task/operations.js +80 -46
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +5 -7
- package/build/src/task/store.js +43 -28
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/execution.d.ts +51 -0
- package/build/src/verification/execution.js +108 -0
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +24 -0
- package/build/src/world.js +136 -0
- package/package.json +8 -4
- package/build/src/akuma/activity.d.ts +0 -66
- package/build/src/akuma/activity.js +0 -139
- package/build/src/akuma/providers/claude.js +0 -305
- package/build/src/context-root.d.ts +0 -4
- package/build/src/context-root.js +0 -15
- package/build/src/git/delivery.d.ts +0 -20
- package/build/src/git/delivery.js +0 -109
- package/build/src/git/verification.d.ts +0 -14
- package/build/src/git/verification.js +0 -56
- package/build/src/protocol/read/audit.d.ts +0 -25
- package/build/src/protocol/read/audit.js +0 -39
- package/build/src/verification/producer.d.ts +0 -23
- package/build/src/verification/producer.js +0 -54
|
@@ -1,38 +1,52 @@
|
|
|
1
1
|
import { type ContractId, type ContractState, type JournalEntry, type SnapshotId } from "../core/facts/types.js";
|
|
2
2
|
import type { ContractsObservation } from "../core/facts/observation.js";
|
|
3
3
|
import { type GitSnapshot, type GitOid, type GitRepository } from "./repository.js";
|
|
4
|
+
import { type GitDecodeChannel, type GitReadObservation, type GitTreeSelection } from "./read-observation.js";
|
|
5
|
+
export type TargetObservation = Readonly<{
|
|
6
|
+
head: SnapshotId | null;
|
|
7
|
+
drift: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function observeDeliveryTargetAt(observation: GitReadObservation, state: ContractState): Promise<TargetObservation | null>;
|
|
4
10
|
type GitJournalRecord = Readonly<{
|
|
5
11
|
entries: readonly JournalEntry[];
|
|
6
12
|
state: ContractState | null;
|
|
7
13
|
}>;
|
|
8
|
-
type
|
|
14
|
+
export type ContractWorldObservation = Readonly<{
|
|
15
|
+
snapshot: SnapshotId | null;
|
|
9
16
|
contracts: ReadonlyMap<ContractId, GitJournalRecord>;
|
|
10
17
|
}>;
|
|
18
|
+
export type ActiveContractWorldObservation = ContractWorldObservation & Readonly<{
|
|
19
|
+
eligibility: ContractsObservation;
|
|
20
|
+
}>;
|
|
11
21
|
export type GitAdmissionSnapshot = Readonly<{
|
|
12
22
|
snapshot: GitSnapshot;
|
|
13
23
|
frozenJournalBytes: ReadonlyMap<GitOid, Buffer>;
|
|
24
|
+
treeDirectories: ReadonlyMap<string, ReadonlyMap<string, import("./tree.js").TreeEntry>>;
|
|
14
25
|
}>;
|
|
15
26
|
export type GitDecisionObservation = Readonly<{
|
|
16
27
|
admission: GitAdmissionSnapshot;
|
|
17
28
|
decision: ContractsObservation;
|
|
18
29
|
journals: ReadonlyMap<ContractId, GitJournalRecord>;
|
|
19
30
|
}>;
|
|
20
|
-
type BindCoordinatesObservation = Readonly<{
|
|
31
|
+
export type BindCoordinatesObservation = Readonly<{
|
|
21
32
|
start: SnapshotId;
|
|
22
33
|
target?: string;
|
|
34
|
+
branch: string | null;
|
|
23
35
|
}>;
|
|
24
|
-
export declare function normalizeTargetBranch(repository: GitRepository, input: string): string | null
|
|
25
|
-
/** Read
|
|
26
|
-
export declare function currentBranch(repository: GitRepository): string | null
|
|
36
|
+
export declare function normalizeTargetBranch(repository: GitRepository, input: string): Promise<string | null>;
|
|
37
|
+
/** Read one worktree's attached branch, or null for detached HEAD. */
|
|
38
|
+
export declare function currentBranch(repository: GitRepository, path?: string): Promise<string | null>;
|
|
27
39
|
/** Observe bind's tender start and optional reward target without creating persistent state. */
|
|
28
|
-
export declare function observeBindCoordinates(repository: GitRepository, requestedTarget?: string): BindCoordinatesObservation | null
|
|
29
|
-
|
|
30
|
-
export declare function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export declare function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export declare function
|
|
37
|
-
export declare function
|
|
40
|
+
export declare function observeBindCoordinates(repository: GitRepository, requestedTarget?: string): Promise<BindCoordinatesObservation | null>;
|
|
41
|
+
export declare function observeActiveContractWorld(observation: GitReadObservation): Promise<ActiveContractWorldObservation>;
|
|
42
|
+
export declare function observeContractWorld(observation: GitReadObservation, requested?: readonly ContractId[]): Promise<ContractWorldObservation>;
|
|
43
|
+
export declare function observeContractsForAdmissionAt(repository: GitRepository, channel: GitDecodeChannel, ids: readonly ContractId[], selection?: GitTreeSelection): Promise<GitDecisionObservation>;
|
|
44
|
+
/** Observe selected Contract journals and their current direct prerequisites in one Git epoch. */
|
|
45
|
+
export declare function observeGitForAdmissionAt(repository: GitRepository, channel: GitDecodeChannel, ids: readonly ContractId[], selection?: GitTreeSelection): Promise<GitDecisionObservation>;
|
|
46
|
+
export declare function withContractReadObservationAt<Value>(repository: GitRepository, channel: GitDecodeChannel, id: ContractId, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
|
|
47
|
+
/** Observe targeted Contract journals within an already frozen Git epoch. */
|
|
48
|
+
export declare function observeContractsForAdmissionInObservationAt(observation: GitReadObservation, ids: readonly ContractId[]): Promise<GitDecisionObservation>;
|
|
49
|
+
export declare function observeContractAt(repository: GitRepository, channel: GitDecodeChannel, id: ContractId): Promise<GitJournalRecord>;
|
|
50
|
+
export declare function extendContractsForAdmissionAt(channel: GitDecodeChannel, observation: GitDecisionObservation, ids: readonly ContractId[]): Promise<GitDecisionObservation>;
|
|
51
|
+
export declare function extendAdmissionPathsAt(channel: GitDecodeChannel, observation: GitDecisionObservation, paths: readonly string[]): Promise<GitDecisionObservation>;
|
|
38
52
|
export {};
|
package/build/src/git/observe.js
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { decodeJournal } from "../core/facts/codec.js";
|
|
2
2
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
3
3
|
import { foldJournal } from "../core/facts/fold.js";
|
|
4
|
-
import { contractJournalPath, mintContractHead, mintSnapshotId } from "./identity.js";
|
|
5
|
-
import { GitPlumbingError, isKeiyakuOwnedRef,
|
|
4
|
+
import { contractJournalPath, contractJournalPaths, mintContractHead, mintSnapshotId, } from "./identity.js";
|
|
5
|
+
import { GitPlumbingError, isKeiyakuOwnedRef, runGit, } from "./repository.js";
|
|
6
|
+
import { readGitTreeSelection, withGitTargetedReadObservation, } from "./read-observation.js";
|
|
7
|
+
export async function observeDeliveryTargetAt(observation, state) {
|
|
8
|
+
const target = state.coordinates.target;
|
|
9
|
+
if (target === undefined)
|
|
10
|
+
return null;
|
|
11
|
+
const value = await observation.resolveRef(target);
|
|
12
|
+
const head = value === null ? null : mintSnapshotId(value);
|
|
13
|
+
const delivery = state.delivery?.data;
|
|
14
|
+
if (delivery === undefined)
|
|
15
|
+
return { head, drift: false };
|
|
16
|
+
const expected = state.terminal?.kind === "claimed"
|
|
17
|
+
? delivery.integration.snapshot
|
|
18
|
+
: delivery.integration.predecessor;
|
|
19
|
+
return { head, drift: head !== expected };
|
|
20
|
+
}
|
|
6
21
|
const TARGET_COORDINATES_FORMAT = "%(refname)%00%(objectname)%00";
|
|
7
|
-
export function normalizeTargetBranch(repository, input) {
|
|
22
|
+
export async function normalizeTargetBranch(repository, input) {
|
|
8
23
|
if (input.includes("\0"))
|
|
9
24
|
return null;
|
|
10
25
|
const prefix = "refs/heads/";
|
|
@@ -15,7 +30,7 @@ export function normalizeTargetBranch(repository, input) {
|
|
|
15
30
|
if (branch.length === 0 || branch.startsWith("-") || isKeiyakuOwnedRef(target))
|
|
16
31
|
return null;
|
|
17
32
|
try {
|
|
18
|
-
const checked = runGit(repository, ["check-ref-format", "--branch", branch]).toString("utf8").trim();
|
|
33
|
+
const checked = (await runGit(repository, ["check-ref-format", "--branch", branch])).toString("utf8").trim();
|
|
19
34
|
return checked === branch ? target : null;
|
|
20
35
|
}
|
|
21
36
|
catch (error) {
|
|
@@ -24,10 +39,15 @@ export function normalizeTargetBranch(repository, input) {
|
|
|
24
39
|
throw error;
|
|
25
40
|
}
|
|
26
41
|
}
|
|
27
|
-
/** Read
|
|
28
|
-
export function currentBranch(repository) {
|
|
42
|
+
/** Read one worktree's attached branch, or null for detached HEAD. */
|
|
43
|
+
export async function currentBranch(repository, path) {
|
|
29
44
|
try {
|
|
30
|
-
const ref = runGit(repository, [
|
|
45
|
+
const ref = (await runGit(repository, [
|
|
46
|
+
...(path === undefined ? [] : ["-C", path]),
|
|
47
|
+
"symbolic-ref",
|
|
48
|
+
"--quiet",
|
|
49
|
+
"HEAD",
|
|
50
|
+
])).toString("utf8").trim();
|
|
31
51
|
return ref.startsWith("refs/heads/") ? ref : null;
|
|
32
52
|
}
|
|
33
53
|
catch (error) {
|
|
@@ -46,10 +66,13 @@ function structuredFields(output, fieldCount) {
|
|
|
46
66
|
return fields.slice(0, -1);
|
|
47
67
|
}
|
|
48
68
|
/** Observe bind's tender start and optional reward target without creating persistent state. */
|
|
49
|
-
export function observeBindCoordinates(repository, requestedTarget) {
|
|
69
|
+
export async function observeBindCoordinates(repository, requestedTarget) {
|
|
50
70
|
if (requestedTarget === undefined) {
|
|
51
71
|
try {
|
|
52
|
-
return {
|
|
72
|
+
return {
|
|
73
|
+
start: mintSnapshotId((await runGit(repository, ["rev-parse", "--verify", "HEAD"])).toString("utf8").trim()),
|
|
74
|
+
branch: await currentBranch(repository),
|
|
75
|
+
};
|
|
53
76
|
}
|
|
54
77
|
catch {
|
|
55
78
|
malformedBindCoordinatesOutput();
|
|
@@ -58,7 +81,7 @@ export function observeBindCoordinates(repository, requestedTarget) {
|
|
|
58
81
|
if (isKeiyakuOwnedRef(requestedTarget)) {
|
|
59
82
|
throw new Error(`bind target names a Keiyaku-owned ref: ${requestedTarget}`);
|
|
60
83
|
}
|
|
61
|
-
const output = runGit(repository, [
|
|
84
|
+
const output = await runGit(repository, [
|
|
62
85
|
"for-each-ref",
|
|
63
86
|
`--format=${TARGET_COORDINATES_FORMAT}`,
|
|
64
87
|
"--",
|
|
@@ -70,7 +93,7 @@ export function observeBindCoordinates(repository, requestedTarget) {
|
|
|
70
93
|
if (target !== requestedTarget || start === undefined)
|
|
71
94
|
malformedBindCoordinatesOutput();
|
|
72
95
|
try {
|
|
73
|
-
return { target, start: mintSnapshotId(start) };
|
|
96
|
+
return { target, start: mintSnapshotId(start), branch: await currentBranch(repository) };
|
|
74
97
|
}
|
|
75
98
|
catch {
|
|
76
99
|
malformedBindCoordinatesOutput();
|
|
@@ -93,35 +116,47 @@ function decodeGitJournal(path, git, bytes, expectedId) {
|
|
|
93
116
|
throw new AuthorityCorruptionError(`journal content does not canonically identify ${path}`);
|
|
94
117
|
}
|
|
95
118
|
const id = first.contract;
|
|
96
|
-
if (
|
|
119
|
+
if (!contractJournalPaths(id).includes(path)) {
|
|
97
120
|
throw new AuthorityCorruptionError(`journal path does not match canonical contract identity: ${path}`);
|
|
98
121
|
}
|
|
99
122
|
return { id, entries, oid: journal.oid };
|
|
100
123
|
}
|
|
101
|
-
function
|
|
124
|
+
function journalClass(state) {
|
|
125
|
+
return state.terminal === null ? "active" : "terminal";
|
|
126
|
+
}
|
|
127
|
+
function observeDecodedJournal(id, decoded, path) {
|
|
128
|
+
const state = foldJournal(id, decoded.entries, mintContractHead(decoded.oid));
|
|
129
|
+
if (path !== undefined && contractJournalPath(id, journalClass(state)) !== path) {
|
|
130
|
+
throw new AuthorityCorruptionError(`journal path class does not match folded state: ${path}`);
|
|
131
|
+
}
|
|
102
132
|
return {
|
|
103
133
|
entries: decoded.entries,
|
|
104
|
-
state
|
|
134
|
+
state,
|
|
105
135
|
};
|
|
106
136
|
}
|
|
107
137
|
function observeFromGit(git, id, blobs) {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
if (
|
|
138
|
+
const matches = contractJournalPaths(id)
|
|
139
|
+
.flatMap((path) => git.paths.has(path) ? [path] : []);
|
|
140
|
+
if (matches.length > 1)
|
|
141
|
+
throw new AuthorityCorruptionError(`duplicate contract journal identity: ${id}`);
|
|
142
|
+
const path = matches[0];
|
|
143
|
+
if (path === undefined)
|
|
111
144
|
return { entries: [], state: null };
|
|
145
|
+
const journal = git.paths.get(path);
|
|
112
146
|
if (journal.type !== "blob")
|
|
113
147
|
throw new AuthorityCorruptionError(`journal path is not a blob: ${path}`);
|
|
114
148
|
const bytes = blobs.get(journal.oid);
|
|
115
149
|
if (bytes === undefined)
|
|
116
150
|
throw new Error(`missing batched journal bytes: ${path}`);
|
|
117
151
|
const decoded = decodeGitJournal(path, git, bytes, id);
|
|
118
|
-
return observeDecodedJournal(id, decoded);
|
|
152
|
+
return observeDecodedJournal(id, decoded, path);
|
|
119
153
|
}
|
|
120
|
-
function enumerateContractObservations(git, blobs) {
|
|
154
|
+
function enumerateContractObservations(git, blobs, journalClass) {
|
|
121
155
|
const observations = new Map();
|
|
122
156
|
const seen = new Set();
|
|
123
157
|
for (const [path, journal] of git.paths) {
|
|
124
|
-
|
|
158
|
+
const match = /^contracts\/(active|terminal)\/[0-9a-f]{2}\/[0-9a-f]{2}\/[0-9a-f]{60}\.jsonl$/u.exec(path);
|
|
159
|
+
if (match === null || (journalClass !== undefined && match[1] !== journalClass))
|
|
125
160
|
continue;
|
|
126
161
|
if (journal.type !== "blob")
|
|
127
162
|
throw new AuthorityCorruptionError(`journal path is not a blob: ${path}`);
|
|
@@ -133,95 +168,169 @@ function enumerateContractObservations(git, blobs) {
|
|
|
133
168
|
if (seen.has(id))
|
|
134
169
|
throw new AuthorityCorruptionError(`duplicate contract journal identity: ${id}`);
|
|
135
170
|
seen.add(id);
|
|
136
|
-
observations.set(id, observeDecodedJournal(id, decoded));
|
|
171
|
+
observations.set(id, observeDecodedJournal(id, decoded, path));
|
|
137
172
|
}
|
|
138
173
|
return observations;
|
|
139
174
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
175
|
+
export async function observeActiveContractWorld(observation) {
|
|
176
|
+
const git = observation.snapshot;
|
|
177
|
+
const journals = [...git.paths]
|
|
178
|
+
.filter(([path, entry]) => path.startsWith("contracts/active/") && path.endsWith(".jsonl") && entry.type === "blob");
|
|
179
|
+
const results = await observation.readBlobs(journals.map(([, entry]) => entry.oid));
|
|
180
|
+
const blobs = new Map();
|
|
181
|
+
for (const [path, entry] of journals) {
|
|
182
|
+
const result = results.get(entry.oid);
|
|
183
|
+
if (result?.kind !== "present")
|
|
184
|
+
throw new AuthorityCorruptionError(`missing Git journal object: ${path}`);
|
|
185
|
+
blobs.set(entry.oid, result.bytes);
|
|
186
|
+
}
|
|
187
|
+
const contracts = new Map(enumerateContractObservations(git, blobs, "active"));
|
|
188
|
+
const prerequisites = [...new Set([...contracts.values()].flatMap((record) => record.state?.terms.after ?? []))];
|
|
189
|
+
const dependencyRecords = await observeTargetedContractsAt(observation, prerequisites);
|
|
190
|
+
return {
|
|
191
|
+
snapshot: git.commit === null ? null : mintSnapshotId(git.commit),
|
|
192
|
+
contracts,
|
|
193
|
+
eligibility: decisionProjection({
|
|
194
|
+
contracts: new Map([...contracts, ...dependencyRecords.contracts]),
|
|
195
|
+
}),
|
|
196
|
+
};
|
|
145
197
|
}
|
|
146
|
-
function
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
.
|
|
198
|
+
export async function observeContractWorld(observation, requested = []) {
|
|
199
|
+
const git = observation.snapshot;
|
|
200
|
+
const journals = [...git.paths]
|
|
201
|
+
.filter(([path, entry]) => /^contracts\/(?:active|terminal)\//u.test(path) && path.endsWith(".jsonl") && entry.type === "blob");
|
|
202
|
+
const results = await observation.readBlobs(journals.map(([, entry]) => entry.oid));
|
|
203
|
+
const blobs = new Map();
|
|
204
|
+
for (const [path, entry] of journals) {
|
|
205
|
+
const result = results.get(entry.oid);
|
|
206
|
+
if (result?.kind !== "present")
|
|
207
|
+
throw new AuthorityCorruptionError(`missing Git journal object: ${path}`);
|
|
208
|
+
blobs.set(entry.oid, result.bytes);
|
|
209
|
+
}
|
|
150
210
|
const contracts = new Map(enumerateContractObservations(git, blobs));
|
|
151
211
|
for (const id of requested) {
|
|
152
212
|
if (!contracts.has(id))
|
|
153
213
|
contracts.set(id, observeFromGit(git, id, blobs));
|
|
154
214
|
}
|
|
155
215
|
return {
|
|
216
|
+
snapshot: git.commit === null ? null : mintSnapshotId(git.commit),
|
|
156
217
|
contracts,
|
|
157
|
-
frozenJournalBytes: blobs,
|
|
158
218
|
};
|
|
159
219
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const git = readGitPaths(repository, ids.map((id) => contractJournalPath(id)));
|
|
163
|
-
const observed = observeFrozenContractsSnapshot(repository, git, ids);
|
|
164
|
-
return { contracts: observed.contracts };
|
|
220
|
+
async function observeTargetedContractsAt(observation, ids) {
|
|
221
|
+
return await observeTargetedContractsFromSnapshotAt(observation.snapshot, observation.readBlobs, ids);
|
|
165
222
|
}
|
|
166
|
-
function
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
223
|
+
async function observeTargetedContractsFromSnapshotAt(snapshot, readBlobsAt, ids) {
|
|
224
|
+
const paths = ids.flatMap(contractJournalPaths);
|
|
225
|
+
const entries = paths.flatMap((path) => {
|
|
226
|
+
const journal = snapshot.paths.get(path);
|
|
227
|
+
return journal?.type === "blob" ? [[path, journal]] : [];
|
|
228
|
+
});
|
|
229
|
+
const results = await readBlobsAt(entries.map(([, entry]) => entry.oid));
|
|
230
|
+
const blobs = new Map();
|
|
231
|
+
for (const [path, entry] of entries) {
|
|
232
|
+
const result = results.get(entry.oid);
|
|
233
|
+
if (result?.kind !== "present")
|
|
234
|
+
throw new AuthorityCorruptionError(`missing Git journal object: ${path}`);
|
|
235
|
+
blobs.set(entry.oid, result.bytes);
|
|
176
236
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
};
|
|
237
|
+
const contracts = new Map();
|
|
238
|
+
for (const id of ids)
|
|
239
|
+
contracts.set(id, observeFromGit(snapshot, id, blobs));
|
|
240
|
+
return { contracts, frozenJournalBytes: blobs };
|
|
181
241
|
}
|
|
182
|
-
function
|
|
183
|
-
return
|
|
242
|
+
export async function observeContractsForAdmissionAt(repository, channel, ids, selection = {}) {
|
|
243
|
+
return withGitTargetedReadObservation(repository, channel, {
|
|
244
|
+
paths: [...ids.flatMap(contractJournalPaths), ...(selection.paths ?? [])],
|
|
245
|
+
...(selection.subtrees === undefined ? {} : { subtrees: selection.subtrees }),
|
|
246
|
+
}, async (observation) => await observeContractsForAdmissionInObservationAt(observation, ids));
|
|
247
|
+
}
|
|
248
|
+
/** Observe selected Contract journals and their current direct prerequisites in one Git epoch. */
|
|
249
|
+
export async function observeGitForAdmissionAt(repository, channel, ids, selection = {}) {
|
|
250
|
+
const observation = await observeContractsForAdmissionAt(repository, channel, ids, selection);
|
|
251
|
+
const prerequisites = [...new Set(ids.flatMap((id) => observation.decision.get(id)?.terms.after ?? []))];
|
|
252
|
+
return await extendContractsForAdmissionAt(channel, observation, prerequisites);
|
|
253
|
+
}
|
|
254
|
+
export function withContractReadObservationAt(repository, channel, id, consume) {
|
|
255
|
+
return withGitTargetedReadObservation(repository, channel, {
|
|
256
|
+
paths: contractJournalPaths(id),
|
|
257
|
+
}, consume);
|
|
184
258
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const contracts =
|
|
259
|
+
/** Observe targeted Contract journals within an already frozen Git epoch. */
|
|
260
|
+
export async function observeContractsForAdmissionInObservationAt(observation, ids) {
|
|
261
|
+
const contracts = await observeTargetedContractsAt(observation, ids);
|
|
188
262
|
return {
|
|
189
|
-
admission: {
|
|
263
|
+
admission: {
|
|
264
|
+
snapshot: observation.snapshot,
|
|
265
|
+
frozenJournalBytes: contracts.frozenJournalBytes,
|
|
266
|
+
treeDirectories: observation.treeDirectories,
|
|
267
|
+
},
|
|
190
268
|
decision: decisionProjection(contracts),
|
|
191
269
|
journals: contracts.contracts,
|
|
192
270
|
};
|
|
193
271
|
}
|
|
194
|
-
|
|
195
|
-
|
|
272
|
+
export async function observeContractAt(repository, channel, id) {
|
|
273
|
+
const observation = await observeContractsForAdmissionAt(repository, channel, [id]);
|
|
274
|
+
const record = observation.journals.get(id);
|
|
275
|
+
if (record === undefined)
|
|
276
|
+
throw new Error(`missing requested contract observation: ${id}`);
|
|
277
|
+
return record;
|
|
278
|
+
}
|
|
279
|
+
export async function extendContractsForAdmissionAt(channel, observation, ids) {
|
|
196
280
|
const missing = ids.filter((id) => !observation.decision.has(id));
|
|
197
281
|
if (missing.length === 0)
|
|
198
282
|
return observation;
|
|
199
|
-
const
|
|
200
|
-
|
|
283
|
+
const readBlobsAt = async (oids) => {
|
|
284
|
+
const objects = await channel.readObjects(oids);
|
|
285
|
+
const blobs = new Map();
|
|
286
|
+
for (const [oid, object] of objects) {
|
|
287
|
+
if (object.kind === "missing")
|
|
288
|
+
blobs.set(oid, object);
|
|
289
|
+
else {
|
|
290
|
+
if (object.type !== "blob")
|
|
291
|
+
throw new AuthorityCorruptionError(`Git object is not a blob: ${oid}`);
|
|
292
|
+
blobs.set(oid, { kind: "present", bytes: object.bytes });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return blobs;
|
|
296
|
+
};
|
|
297
|
+
const snapshot = observation.admission.snapshot;
|
|
298
|
+
if (snapshot.tree === null)
|
|
299
|
+
return observation;
|
|
300
|
+
const selected = await readGitTreeSelection(channel, snapshot.tree, {
|
|
301
|
+
paths: missing.flatMap(contractJournalPaths),
|
|
302
|
+
});
|
|
303
|
+
const extendedSnapshot = {
|
|
304
|
+
...snapshot,
|
|
305
|
+
paths: new Map([...snapshot.paths, ...selected.paths]),
|
|
306
|
+
};
|
|
307
|
+
const added = await observeTargetedContractsFromSnapshotAt(extendedSnapshot, readBlobsAt, missing);
|
|
201
308
|
return {
|
|
202
309
|
admission: {
|
|
203
|
-
snapshot,
|
|
204
|
-
frozenJournalBytes: new Map([
|
|
205
|
-
|
|
206
|
-
...added.frozenJournalBytes,
|
|
207
|
-
]),
|
|
310
|
+
snapshot: extendedSnapshot,
|
|
311
|
+
frozenJournalBytes: new Map([...observation.admission.frozenJournalBytes, ...added.frozenJournalBytes]),
|
|
312
|
+
treeDirectories: new Map([...observation.admission.treeDirectories, ...selected.directories]),
|
|
208
313
|
},
|
|
209
314
|
decision: new Map([...observation.decision, ...decisionProjection(added)]),
|
|
210
315
|
journals: new Map([...observation.journals, ...added.contracts]),
|
|
211
316
|
};
|
|
212
317
|
}
|
|
213
|
-
export function
|
|
214
|
-
|
|
215
|
-
|
|
318
|
+
export async function extendAdmissionPathsAt(channel, observation, paths) {
|
|
319
|
+
if (paths.length === 0 || observation.admission.snapshot.tree === null)
|
|
320
|
+
return observation;
|
|
321
|
+
const selected = await readGitTreeSelection(channel, observation.admission.snapshot.tree, { paths });
|
|
216
322
|
return {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
323
|
+
...observation,
|
|
324
|
+
admission: {
|
|
325
|
+
...observation.admission,
|
|
326
|
+
snapshot: {
|
|
327
|
+
...observation.admission.snapshot,
|
|
328
|
+
paths: new Map([...observation.admission.snapshot.paths, ...selected.paths]),
|
|
329
|
+
},
|
|
330
|
+
treeDirectories: new Map([...observation.admission.treeDirectories, ...selected.directories]),
|
|
331
|
+
},
|
|
220
332
|
};
|
|
221
333
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (observation === undefined)
|
|
225
|
-
throw new Error(`missing requested contract observation: ${id}`);
|
|
226
|
-
return observation;
|
|
334
|
+
function decisionProjection(observation) {
|
|
335
|
+
return new Map([...observation.contracts].map(([id, record]) => [id, record.state]));
|
|
227
336
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type TreeEntry } from "./tree.js";
|
|
2
|
+
import { type GitOid, type GitRepository, type GitSnapshot } from "./repository.js";
|
|
3
|
+
declare const gitReadObservationBrand: unique symbol;
|
|
4
|
+
declare const gitDecodeChannelBrand: unique symbol;
|
|
5
|
+
export type GitBlobResult = Readonly<{
|
|
6
|
+
kind: "present";
|
|
7
|
+
bytes: Buffer;
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
kind: "missing";
|
|
10
|
+
}>;
|
|
11
|
+
export type GitReadObservation = Readonly<{
|
|
12
|
+
readonly [gitReadObservationBrand]: true;
|
|
13
|
+
repository: GitRepository;
|
|
14
|
+
snapshot: GitSnapshot;
|
|
15
|
+
treeDirectories: ReadonlyMap<string, ReadonlyMap<string, TreeEntry>>;
|
|
16
|
+
readBlobs(oids: readonly GitOid[]): Promise<ReadonlyMap<GitOid, GitBlobResult>>;
|
|
17
|
+
resolveRef(ref: string): Promise<GitOid | null>;
|
|
18
|
+
}>;
|
|
19
|
+
export type GitObjectResult = Readonly<{
|
|
20
|
+
kind: "present";
|
|
21
|
+
type: string;
|
|
22
|
+
bytes: Buffer;
|
|
23
|
+
}> | Readonly<{
|
|
24
|
+
kind: "missing";
|
|
25
|
+
}>;
|
|
26
|
+
export type GitDecodeChannel = Readonly<{
|
|
27
|
+
readonly [gitDecodeChannelBrand]: true;
|
|
28
|
+
readObjects(oids: readonly GitOid[]): Promise<ReadonlyMap<GitOid, GitObjectResult>>;
|
|
29
|
+
}>;
|
|
30
|
+
export type GitTreeSelection = Readonly<{
|
|
31
|
+
paths?: readonly string[];
|
|
32
|
+
subtrees?: readonly string[];
|
|
33
|
+
}>;
|
|
34
|
+
export declare function readGitTreeSelection(channel: GitDecodeChannel, root: GitOid, selection: GitTreeSelection): Promise<Readonly<{
|
|
35
|
+
paths: ReadonlyMap<string, TreeEntry>;
|
|
36
|
+
directories: ReadonlyMap<string, ReadonlyMap<string, TreeEntry>>;
|
|
37
|
+
}>>;
|
|
38
|
+
export declare function withGitDecodeChannel<Value>(repository: GitRepository, consume: (channel: GitDecodeChannel) => Value | PromiseLike<Value>): Promise<Value>;
|
|
39
|
+
export declare function withGitReadObservation<Value>(repository: GitRepository, channel: GitDecodeChannel, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
|
|
40
|
+
export declare function withGitTargetedReadObservation<Value>(repository: GitRepository, channel: GitDecodeChannel, selection: GitTreeSelection, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
|
|
41
|
+
export {};
|