@sqdr2/dsh-fusion 0.0.0-stage → 0.3.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/INSTALL.md +89 -0
- package/INSTALL.zh.md +86 -0
- package/LICENSE +201 -0
- package/README.en.md +193 -0
- package/README.md +182 -2
- package/RELEASING.md +123 -0
- package/RELEASING.zh.md +115 -0
- package/contracts/fusion.ts +279 -0
- package/contracts/storage.sql +86 -0
- package/cordis.patch.yml +3 -0
- package/docs/COMPATIBILITY.md +162 -0
- package/docs/EVIDENCE.md +141 -0
- package/dshx.yml +39 -0
- package/lib/client.js +1920 -0
- package/lib/client.js.map +1 -0
- package/lib/dsh-fusion.js +12664 -0
- package/lib/types/activity.d.ts +20 -0
- package/lib/types/approval/logical.d.ts +10 -0
- package/lib/types/benchmark/naive.d.ts +37 -0
- package/lib/types/benchmark/native-run.d.ts +68 -0
- package/lib/types/benchmark/output-limits.d.ts +19 -0
- package/lib/types/bilingual.d.ts +2 -0
- package/lib/types/client/ActivityRows.d.ts +8 -0
- package/lib/types/client/FusionCache.d.ts +4 -0
- package/lib/types/client/FusionHint.d.ts +9 -0
- package/lib/types/client/FusionHistory.d.ts +5 -0
- package/lib/types/client/FusionPanelIcon.d.ts +13 -0
- package/lib/types/client/FusionRecovery.d.ts +5 -0
- package/lib/types/client/FusionSettings.d.ts +9 -0
- package/lib/types/client/FusionStatus.d.ts +5 -0
- package/lib/types/client/FusionTool.d.ts +4 -0
- package/lib/types/client/activity-model.d.ts +14 -0
- package/lib/types/client/i18n.d.ts +15 -0
- package/lib/types/client/index.d.ts +22 -0
- package/lib/types/client/settings-events.d.ts +2 -0
- package/lib/types/client/status-polling.d.ts +9 -0
- package/lib/types/context/guard.d.ts +21 -0
- package/lib/types/context/handoff.d.ts +17 -0
- package/lib/types/contracts.d.ts +449 -0
- package/lib/types/digest.d.ts +5 -0
- package/lib/types/dsh-fusion.d.ts +13 -0
- package/lib/types/errors.d.ts +28 -0
- package/lib/types/evidence/gate.d.ts +23 -0
- package/lib/types/evidence/receipts.d.ts +65 -0
- package/lib/types/execution/write-lease.d.ts +42 -0
- package/lib/types/host/bindings.d.ts +30 -0
- package/lib/types/host/cache-defaults.d.ts +48 -0
- package/lib/types/host/cache-policy.d.ts +155 -0
- package/lib/types/host/change-evidence.d.ts +38 -0
- package/lib/types/host/compaction-routing.d.ts +15 -0
- package/lib/types/host/coordinator.d.ts +169 -0
- package/lib/types/host/evidence-page.d.ts +13 -0
- package/lib/types/host/history.d.ts +88 -0
- package/lib/types/host/http.d.ts +4 -0
- package/lib/types/host/model-output.d.ts +13 -0
- package/lib/types/host/native-activity.d.ts +26 -0
- package/lib/types/host/native-approvals.d.ts +29 -0
- package/lib/types/host/native-auxiliary.d.ts +17 -0
- package/lib/types/host/native-budget.d.ts +33 -0
- package/lib/types/host/native-checks.d.ts +104 -0
- package/lib/types/host/native-compaction.d.ts +8 -0
- package/lib/types/host/native-context.d.ts +36 -0
- package/lib/types/host/native-effects.d.ts +75 -0
- package/lib/types/host/native-evidence.d.ts +4 -0
- package/lib/types/host/native-exploration.d.ts +15 -0
- package/lib/types/host/native-keepalive.d.ts +82 -0
- package/lib/types/host/native-model-control.d.ts +99 -0
- package/lib/types/host/native-on-demand-context.d.ts +39 -0
- package/lib/types/host/native-request.d.ts +5 -0
- package/lib/types/host/native-review.d.ts +11 -0
- package/lib/types/host/native-role-sandbox.d.ts +49 -0
- package/lib/types/host/native-scopes.d.ts +49 -0
- package/lib/types/host/native-selection.d.ts +29 -0
- package/lib/types/host/native-task-context.d.ts +39 -0
- package/lib/types/host/native-usage.d.ts +46 -0
- package/lib/types/host/native-worker-brief.d.ts +74 -0
- package/lib/types/host/native-worker-notices.d.ts +15 -0
- package/lib/types/host/native-worker.d.ts +44 -0
- package/lib/types/host/native-workflow.d.ts +41 -0
- package/lib/types/host/route-transport.d.ts +22 -0
- package/lib/types/host/settings.d.ts +39 -0
- package/lib/types/host/shell.d.ts +11 -0
- package/lib/types/host/status.d.ts +7 -0
- package/lib/types/host/subagent-seam.d.ts +10 -0
- package/lib/types/host/tool-table.d.ts +35 -0
- package/lib/types/host/worker-terminal.d.ts +68 -0
- package/lib/types/host/workspace-guard.d.ts +13 -0
- package/lib/types/host/workspace.d.ts +52 -0
- package/lib/types/identity.d.ts +64 -0
- package/lib/types/index.d.ts +34 -0
- package/lib/types/message-source.d.ts +29 -0
- package/lib/types/profile/compactor.d.ts +5 -0
- package/lib/types/profile/keepalive.d.ts +3 -0
- package/lib/types/profile/resolve.d.ts +17 -0
- package/lib/types/prompts.d.ts +8 -0
- package/lib/types/recovery/reconcile.d.ts +28 -0
- package/lib/types/review/dispatch.d.ts +20 -0
- package/lib/types/review/protocol.d.ts +51 -0
- package/lib/types/review/ticket.d.ts +32 -0
- package/lib/types/status.d.ts +88 -0
- package/lib/types/store-migration.d.ts +29 -0
- package/lib/types/task/deletion.d.ts +64 -0
- package/lib/types/task/reducer.d.ts +6 -0
- package/lib/types/task/sqlite-store.d.ts +71 -0
- package/lib/types/task/state.d.ts +51 -0
- package/lib/types/task/status-index.d.ts +28 -0
- package/lib/types/task/store.d.ts +48 -0
- package/lib/types/usage/budget.d.ts +27 -0
- package/lib/types/usage/ledger.d.ts +66 -0
- package/lib/types/usage/normalize.d.ts +50 -0
- package/lib/types/usage/pricing.d.ts +18 -0
- package/package.json +178 -4
- package/profiles/fusion-auto.example.json +45 -0
- package/prompts/compact.md +7 -0
- package/prompts/lead.md +42 -0
- package/prompts/model-lead.md +13 -0
- package/prompts/model-worker.md +5 -0
- package/prompts/worker.md +21 -0
- package/src/activity.ts +23 -0
- package/src/approval/logical.ts +44 -0
- package/src/benchmark/naive.ts +216 -0
- package/src/benchmark/native-run.ts +215 -0
- package/src/benchmark/output-limits.ts +33 -0
- package/src/bilingual.ts +2 -0
- package/src/client/ActivityRows.tsx +59 -0
- package/src/client/FusionCache.tsx +130 -0
- package/src/client/FusionHint.tsx +39 -0
- package/src/client/FusionHistory.tsx +247 -0
- package/src/client/FusionPanelIcon.tsx +39 -0
- package/src/client/FusionRecovery.tsx +69 -0
- package/src/client/FusionSettings.tsx +205 -0
- package/src/client/FusionStatus.tsx +103 -0
- package/src/client/FusionTool.tsx +66 -0
- package/src/client/activity-model.ts +31 -0
- package/src/client/i18n.ts +30 -0
- package/src/client/index.ts +50 -0
- package/src/client/settings-events.ts +3 -0
- package/src/client/status-polling.ts +88 -0
- package/src/context/guard.ts +81 -0
- package/src/context/handoff.ts +28 -0
- package/src/contracts.ts +449 -0
- package/src/digest.ts +28 -0
- package/src/dsh-fusion.ts +321 -0
- package/src/errors.ts +34 -0
- package/src/evidence/gate.ts +290 -0
- package/src/evidence/receipts.ts +175 -0
- package/src/execution/write-lease.ts +187 -0
- package/src/host/bindings.ts +91 -0
- package/src/host/cache-defaults.ts +103 -0
- package/src/host/cache-policy.ts +168 -0
- package/src/host/change-evidence.ts +156 -0
- package/src/host/compaction-routing.ts +46 -0
- package/src/host/coordinator.ts +2160 -0
- package/src/host/evidence-page.ts +25 -0
- package/src/host/history.ts +114 -0
- package/src/host/http.ts +30 -0
- package/src/host/model-output.ts +22 -0
- package/src/host/native-activity.ts +199 -0
- package/src/host/native-approvals.ts +196 -0
- package/src/host/native-auxiliary.ts +19 -0
- package/src/host/native-budget.ts +112 -0
- package/src/host/native-checks.ts +474 -0
- package/src/host/native-compaction.ts +34 -0
- package/src/host/native-context.ts +204 -0
- package/src/host/native-effects.ts +260 -0
- package/src/host/native-evidence.ts +31 -0
- package/src/host/native-exploration.ts +114 -0
- package/src/host/native-keepalive.ts +292 -0
- package/src/host/native-model-control.ts +298 -0
- package/src/host/native-on-demand-context.ts +74 -0
- package/src/host/native-request.ts +12 -0
- package/src/host/native-review.ts +51 -0
- package/src/host/native-role-sandbox.ts +171 -0
- package/src/host/native-scopes.ts +203 -0
- package/src/host/native-selection.ts +110 -0
- package/src/host/native-task-context.ts +264 -0
- package/src/host/native-usage.ts +121 -0
- package/src/host/native-worker-brief.ts +122 -0
- package/src/host/native-worker-notices.ts +72 -0
- package/src/host/native-worker.ts +215 -0
- package/src/host/native-workflow.ts +103 -0
- package/src/host/route-transport.ts +54 -0
- package/src/host/settings.ts +93 -0
- package/src/host/shell.ts +13 -0
- package/src/host/status.ts +112 -0
- package/src/host/subagent-seam.ts +20 -0
- package/src/host/tool-table.ts +56 -0
- package/src/host/worker-terminal.ts +91 -0
- package/src/host/workspace-guard.ts +17 -0
- package/src/host/workspace.ts +184 -0
- package/src/identity.ts +76 -0
- package/src/index.ts +50 -0
- package/src/message-source.ts +31 -0
- package/src/profile/compactor.ts +26 -0
- package/src/profile/keepalive.ts +13 -0
- package/src/profile/resolve.ts +131 -0
- package/src/prompts.ts +32 -0
- package/src/recovery/reconcile.ts +38 -0
- package/src/review/dispatch.ts +48 -0
- package/src/review/protocol.ts +212 -0
- package/src/review/ticket.ts +166 -0
- package/src/status.ts +55 -0
- package/src/store-migration.ts +65 -0
- package/src/task/deletion.ts +105 -0
- package/src/task/reducer.ts +679 -0
- package/src/task/sqlite-store.ts +386 -0
- package/src/task/state.ts +72 -0
- package/src/task/status-index.ts +198 -0
- package/src/task/store.ts +287 -0
- package/src/usage/budget.ts +88 -0
- package/src/usage/ledger.ts +218 -0
- package/src/usage/normalize.ts +308 -0
- package/src/usage/pricing.ts +95 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin-domain contracts for dsh-fusion.
|
|
3
|
+
* These are proposed types, not existing DSH API declarations.
|
|
4
|
+
* Convert DSH branded IDs only in a version-pinned bridge (not landed).
|
|
5
|
+
*/
|
|
6
|
+
export type Brand<T, B extends string> = T & {
|
|
7
|
+
readonly __brand: B;
|
|
8
|
+
};
|
|
9
|
+
export type TaskId = Brand<string, 'FusionTaskId'>;
|
|
10
|
+
export type SessionId = Brand<string, 'DshSessionId'>;
|
|
11
|
+
export type WorkOrderId = Brand<string, 'FusionWorkOrderId'>;
|
|
12
|
+
export type OperationId = Brand<string, 'FusionOperationId'>;
|
|
13
|
+
export type ArtifactId = Brand<string, 'FusionArtifactId'>;
|
|
14
|
+
export type SnapshotId = Brand<string, 'FusionSnapshotId'>;
|
|
15
|
+
export type Digest = Brand<string, 'Sha256Hex'>;
|
|
16
|
+
export type UsdDecimal = Brand<string, 'UsdDecimal'>;
|
|
17
|
+
export type EpochId = Brand<string, 'ContextEpochId'>;
|
|
18
|
+
export declare const TaskId: (raw: string) => TaskId;
|
|
19
|
+
export declare const SessionId: (raw: string) => SessionId;
|
|
20
|
+
export declare const WorkOrderId: (raw: string) => WorkOrderId;
|
|
21
|
+
export declare const OperationId: (raw: string) => OperationId;
|
|
22
|
+
export declare const ArtifactId: (raw: string) => ArtifactId;
|
|
23
|
+
export declare const SnapshotId: (raw: string) => SnapshotId;
|
|
24
|
+
export declare const EpochId: (raw: string) => EpochId;
|
|
25
|
+
export declare const UsdDecimal: (raw: string) => UsdDecimal;
|
|
26
|
+
export interface PhysicalRoute {
|
|
27
|
+
provider: string;
|
|
28
|
+
model: string;
|
|
29
|
+
reasoningEffort?: string;
|
|
30
|
+
}
|
|
31
|
+
export type RunSelection = {
|
|
32
|
+
kind: 'model';
|
|
33
|
+
route: PhysicalRoute;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'profile';
|
|
36
|
+
profileId: string;
|
|
37
|
+
requestedVersion?: string;
|
|
38
|
+
};
|
|
39
|
+
export type Role = 'lead' | 'worker';
|
|
40
|
+
export type Phase = 'READY' | 'PLANNING' | 'DIRECT' | 'WORKER_RUNNING' | 'REVIEWING' | 'REWORK' | 'WAITING_APPROVAL' | 'WAITING_USER' | 'WAITING_BUDGET' | 'RECOVERING' | 'PAUSED' | 'STOPPING' | 'NEEDS_DECISION' | 'FAILED' | 'COMPLETED' | 'CANCELLED';
|
|
41
|
+
export type VerificationLevel = 'unverified' | 'partial' | 'verified';
|
|
42
|
+
export type ExecutionIntent = 'DIRECT' | 'DELEGATE';
|
|
43
|
+
export interface SourceRef {
|
|
44
|
+
sessionId: SessionId;
|
|
45
|
+
eventSeq: number;
|
|
46
|
+
messageId?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ArtifactRef {
|
|
49
|
+
id: ArtifactId;
|
|
50
|
+
digest: Digest;
|
|
51
|
+
ownerTaskId: TaskId;
|
|
52
|
+
mediaType: string;
|
|
53
|
+
bytes: number;
|
|
54
|
+
}
|
|
55
|
+
export interface Constraint {
|
|
56
|
+
id: string;
|
|
57
|
+
text: string;
|
|
58
|
+
source: SourceRef;
|
|
59
|
+
provenance: 'user' | 'policy' | 'inferred';
|
|
60
|
+
mandatory: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface AcceptanceCriterion {
|
|
63
|
+
id: string;
|
|
64
|
+
description: string;
|
|
65
|
+
verificationKind: 'test' | 'static-check' | 'human' | 'review';
|
|
66
|
+
mandatory: boolean;
|
|
67
|
+
/** Frozen verifier id. When set, only that registered verifier may satisfy the criterion. */
|
|
68
|
+
verifierId?: string;
|
|
69
|
+
/** Frozen CheckPlan id. Test/static criteria require a registered plan. */
|
|
70
|
+
planId?: string;
|
|
71
|
+
planDigest?: Digest;
|
|
72
|
+
}
|
|
73
|
+
export interface ResourcePolicy {
|
|
74
|
+
maxWorkerSteps: number;
|
|
75
|
+
maxReworkRounds: number;
|
|
76
|
+
maxCapabilityUpgrades: number;
|
|
77
|
+
modelSpendAuthorizationId?: string;
|
|
78
|
+
maxApiCostUsd?: UsdDecimal;
|
|
79
|
+
/** Legacy serialized planning field, not enforced by the native coordinator.
|
|
80
|
+
* Native runs use the separately approved request/reservation ledger and omit
|
|
81
|
+
* this field; old work orders retain it as historical data, not a hard cap. */
|
|
82
|
+
maxTotalOutputTokens?: number;
|
|
83
|
+
commandMaxSeconds: number;
|
|
84
|
+
}
|
|
85
|
+
export interface WorkOrder {
|
|
86
|
+
schemaVersion: 1;
|
|
87
|
+
/** Older work orders are implementation work. Exploration never grants a writer. */
|
|
88
|
+
mode?: 'explore' | 'implement' | 'text';
|
|
89
|
+
taskId: TaskId;
|
|
90
|
+
id: WorkOrderId;
|
|
91
|
+
operationId: OperationId;
|
|
92
|
+
revision: number;
|
|
93
|
+
goal: string;
|
|
94
|
+
constraints: readonly Constraint[];
|
|
95
|
+
acceptance: readonly AcceptanceCriterion[];
|
|
96
|
+
allowedPaths: readonly string[];
|
|
97
|
+
forbiddenActions: readonly string[];
|
|
98
|
+
baseSnapshot: SnapshotId;
|
|
99
|
+
evidence: readonly ArtifactRef[];
|
|
100
|
+
decisions: readonly {
|
|
101
|
+
text: string;
|
|
102
|
+
source: SourceRef;
|
|
103
|
+
}[];
|
|
104
|
+
uncertainties: readonly string[];
|
|
105
|
+
policy: ResourcePolicy;
|
|
106
|
+
}
|
|
107
|
+
export interface ExplorationSource {
|
|
108
|
+
path: string;
|
|
109
|
+
startLine: number;
|
|
110
|
+
endLine: number;
|
|
111
|
+
}
|
|
112
|
+
/** File excerpts are captured by the Host, not accepted from model narration. */
|
|
113
|
+
export interface ExplorationReport {
|
|
114
|
+
schemaVersion: 1;
|
|
115
|
+
workOrderId: WorkOrderId;
|
|
116
|
+
revision: number;
|
|
117
|
+
status: WorkerReport['status'];
|
|
118
|
+
summary: string;
|
|
119
|
+
unresolved: readonly string[];
|
|
120
|
+
snapshot: SnapshotId;
|
|
121
|
+
sources: readonly (ExplorationSource & {
|
|
122
|
+
fileDigest: string;
|
|
123
|
+
excerpt: ArtifactRef;
|
|
124
|
+
})[];
|
|
125
|
+
}
|
|
126
|
+
export interface CoverageClaim {
|
|
127
|
+
criterionId: string;
|
|
128
|
+
state: 'satisfied' | 'not-satisfied' | 'not-verified';
|
|
129
|
+
evidenceIds: readonly ArtifactId[];
|
|
130
|
+
explanation: string;
|
|
131
|
+
}
|
|
132
|
+
export interface WorkerReport {
|
|
133
|
+
schemaVersion: 1;
|
|
134
|
+
workOrderId: WorkOrderId;
|
|
135
|
+
revision: number;
|
|
136
|
+
status: 'completed' | 'blocked' | 'needs-decision';
|
|
137
|
+
summary: string;
|
|
138
|
+
snapshot: SnapshotId;
|
|
139
|
+
changeManifest: ArtifactRef;
|
|
140
|
+
coverage: readonly CoverageClaim[];
|
|
141
|
+
verification: readonly ArtifactRef[];
|
|
142
|
+
unresolved: readonly string[];
|
|
143
|
+
questions: readonly string[];
|
|
144
|
+
}
|
|
145
|
+
export type EvidenceKind = 'tool' | 'human-decision' | 'review-accept';
|
|
146
|
+
export interface ToolEvidence {
|
|
147
|
+
schemaVersion: 1;
|
|
148
|
+
taskId: TaskId;
|
|
149
|
+
operationId: OperationId;
|
|
150
|
+
actor: SessionId;
|
|
151
|
+
nativeToolCallId: string;
|
|
152
|
+
argvDigest: Digest;
|
|
153
|
+
cwdDigest: Digest;
|
|
154
|
+
inputSnapshot: SnapshotId;
|
|
155
|
+
outputSnapshot?: SnapshotId;
|
|
156
|
+
exitCode: number | null;
|
|
157
|
+
startedAt: string;
|
|
158
|
+
endedAt: string | null;
|
|
159
|
+
stdout: ArtifactRef;
|
|
160
|
+
stderr: ArtifactRef;
|
|
161
|
+
state: 'started' | 'completed' | 'cancelled' | 'outcome-unknown';
|
|
162
|
+
/** Default `tool`. Human/review criteria require their own kinds. */
|
|
163
|
+
kind?: EvidenceKind;
|
|
164
|
+
}
|
|
165
|
+
export interface ContextCheckpoint {
|
|
166
|
+
schemaVersion: 1;
|
|
167
|
+
epochId: EpochId;
|
|
168
|
+
taskId: TaskId;
|
|
169
|
+
revision: number;
|
|
170
|
+
goal: string;
|
|
171
|
+
mandatoryConstraints: readonly Constraint[];
|
|
172
|
+
snapshot: SnapshotId;
|
|
173
|
+
decisions: readonly {
|
|
174
|
+
text: string;
|
|
175
|
+
source: SourceRef;
|
|
176
|
+
}[];
|
|
177
|
+
coverage: readonly CoverageClaim[];
|
|
178
|
+
pendingApprovalIds: readonly string[];
|
|
179
|
+
openQuestions: readonly string[];
|
|
180
|
+
evidence: readonly ArtifactRef[];
|
|
181
|
+
sourceSurfaceSeqs: readonly number[];
|
|
182
|
+
digest: Digest;
|
|
183
|
+
}
|
|
184
|
+
export interface RoleContextPolicy {
|
|
185
|
+
targetInputTokens: number;
|
|
186
|
+
reserveOutputTokens: number;
|
|
187
|
+
minSafetyTokens: number;
|
|
188
|
+
safetyFraction: number;
|
|
189
|
+
compactToFraction: number;
|
|
190
|
+
evidenceReadTokens: number;
|
|
191
|
+
maxToolVisibleTokens: number;
|
|
192
|
+
}
|
|
193
|
+
export interface PairProfile {
|
|
194
|
+
schemaVersion: 1;
|
|
195
|
+
id: string;
|
|
196
|
+
version: string;
|
|
197
|
+
digest: Digest;
|
|
198
|
+
enabled: boolean;
|
|
199
|
+
quality: 'experimental' | 'validated' | 'deprecated';
|
|
200
|
+
/** Missing on frozen v1 sessions; only new selections use native model behavior. */
|
|
201
|
+
interactionMode?: 'model-like';
|
|
202
|
+
/** Frozen per selection. Absence preserves pre-enforcement sessions. */
|
|
203
|
+
workflowPolicy?: 'enforced-v1' | 'enforced-v2' | 'enforced-v3';
|
|
204
|
+
lead: PhysicalRoute;
|
|
205
|
+
worker: PhysicalRoute;
|
|
206
|
+
workerUpgradePath: readonly PhysicalRoute[];
|
|
207
|
+
promptDigests: Readonly<Record<'lead' | 'worker' | 'compact', Digest>>;
|
|
208
|
+
context: Readonly<Record<Role, RoleContextPolicy>>;
|
|
209
|
+
/** Explicit per-route opt-in; absence preserves old frozen profile digests. */
|
|
210
|
+
/** Per role: on, off, or 'auto' (armed once the route reports cache reads). Unset: Lead auto, Worker off. */
|
|
211
|
+
cacheKeepalive?: Readonly<Record<Role, boolean | 'auto'>>;
|
|
212
|
+
/** Optional explicit summary route; absence preserves the role model and old digests. */
|
|
213
|
+
compactor?: {
|
|
214
|
+
readonly route: PhysicalRoute;
|
|
215
|
+
readonly maxOutputTokens: number;
|
|
216
|
+
};
|
|
217
|
+
dataPolicyId: string;
|
|
218
|
+
evidenceCampaignIds: readonly string[];
|
|
219
|
+
}
|
|
220
|
+
export interface LogicalApproval {
|
|
221
|
+
id: string;
|
|
222
|
+
taskId: TaskId;
|
|
223
|
+
revision: number;
|
|
224
|
+
operationId: OperationId;
|
|
225
|
+
nativeRequestId?: string;
|
|
226
|
+
requestingAgent?: SessionId;
|
|
227
|
+
toolName?: string;
|
|
228
|
+
callId?: string;
|
|
229
|
+
role?: Role;
|
|
230
|
+
reason?: string;
|
|
231
|
+
argsDigest: Digest;
|
|
232
|
+
snapshot: SnapshotId;
|
|
233
|
+
permissionPolicyDigest: Digest;
|
|
234
|
+
state: 'pending' | 'approved' | 'rejected' | 'withdrawn' | 'consumed';
|
|
235
|
+
decisionBy?: 'human' | 'preauthorized-policy';
|
|
236
|
+
}
|
|
237
|
+
export interface WriteLease {
|
|
238
|
+
workspaceId: string;
|
|
239
|
+
holder: SessionId;
|
|
240
|
+
taskId: TaskId;
|
|
241
|
+
generation: number;
|
|
242
|
+
activeOperationIds: readonly OperationId[];
|
|
243
|
+
}
|
|
244
|
+
export interface TokenMeasurement {
|
|
245
|
+
inputTokens: number;
|
|
246
|
+
reservedOutputTokens: number;
|
|
247
|
+
contextWindow: number;
|
|
248
|
+
safetyTokens: number;
|
|
249
|
+
quality: 'exact' | 'provider-estimated' | 'heuristic';
|
|
250
|
+
requestDigest: Digest;
|
|
251
|
+
}
|
|
252
|
+
export type UsageApplicability = 'not_applicable' | 'unknown' | 'known';
|
|
253
|
+
export interface NormalizedUsage {
|
|
254
|
+
uncachedInput: number | null;
|
|
255
|
+
cacheRead: number | null;
|
|
256
|
+
cacheReadStatus: UsageApplicability;
|
|
257
|
+
cacheWrite: Readonly<Record<string, number | null>>;
|
|
258
|
+
cacheWriteStatus: Readonly<Record<string, UsageApplicability>>;
|
|
259
|
+
output: number | null;
|
|
260
|
+
/** Informational subset already inside `output`. Do not charge again. */
|
|
261
|
+
reasoningOutputSubset: number | null;
|
|
262
|
+
/** Separately billed reasoning. Charge at the reasoning or output rate. */
|
|
263
|
+
reasoningSeparate: number | null;
|
|
264
|
+
/** Reasoning tokens whose include-in-output contract is unknown. Never assume free or included. */
|
|
265
|
+
reasoningUnspecified: number | null;
|
|
266
|
+
/** Explicit billing relation. Never infer not_applicable from a null quantity. */
|
|
267
|
+
reasoningBilling: ReasoningBilling;
|
|
268
|
+
/** Null when the provider contract was not stated. */
|
|
269
|
+
inputIncludesCacheRead: boolean | null;
|
|
270
|
+
}
|
|
271
|
+
export interface ReasoningBilling {
|
|
272
|
+
kind: 'included' | 'separate' | 'unknown' | 'not_applicable';
|
|
273
|
+
tokens: number | null;
|
|
274
|
+
}
|
|
275
|
+
export interface UsageAttempt {
|
|
276
|
+
attemptId: string;
|
|
277
|
+
taskId: TaskId;
|
|
278
|
+
agentId: SessionId;
|
|
279
|
+
role: Role;
|
|
280
|
+
purpose: 'conversation' | 'compaction' | 'review' | 'routing' | 'other';
|
|
281
|
+
route: PhysicalRoute;
|
|
282
|
+
epochId: EpochId;
|
|
283
|
+
serviceTier?: string;
|
|
284
|
+
rawUsage?: ArtifactRef;
|
|
285
|
+
normalized: NormalizedUsage;
|
|
286
|
+
priceCardDigest?: Digest;
|
|
287
|
+
apiEquivalentUsd: UsdDecimal | null;
|
|
288
|
+
actualBilledUsd: UsdDecimal | null;
|
|
289
|
+
status: 'pending' | 'complete' | 'partial' | 'unknown';
|
|
290
|
+
}
|
|
291
|
+
export interface EventEnvelope<T extends string, P> {
|
|
292
|
+
schemaVersion: 1;
|
|
293
|
+
id: string;
|
|
294
|
+
taskId: TaskId;
|
|
295
|
+
seq: number;
|
|
296
|
+
revision: number;
|
|
297
|
+
type: T;
|
|
298
|
+
createdAt: string;
|
|
299
|
+
causeId: string;
|
|
300
|
+
payload: P;
|
|
301
|
+
}
|
|
302
|
+
export interface ReviewGate {
|
|
303
|
+
taskId: TaskId;
|
|
304
|
+
workOrderId: WorkOrderId;
|
|
305
|
+
revision: number;
|
|
306
|
+
reportDigest: Digest;
|
|
307
|
+
snapshot: SnapshotId;
|
|
308
|
+
reviewAttemptId: string;
|
|
309
|
+
decision: 'accept' | 'rework' | 'needs-decision' | 'REVIEW_INCOMPLETE';
|
|
310
|
+
terminalStatus: 'accepting' | 'incomplete' | 'rework' | 'needs-decision' | 'legacy-unbound';
|
|
311
|
+
}
|
|
312
|
+
export interface ReportSubject {
|
|
313
|
+
taskId: TaskId;
|
|
314
|
+
workOrderId: WorkOrderId;
|
|
315
|
+
revision: number;
|
|
316
|
+
reportId: string;
|
|
317
|
+
reportDigest: Digest;
|
|
318
|
+
snapshot: SnapshotId;
|
|
319
|
+
}
|
|
320
|
+
export interface ReviewReadinessReceipt {
|
|
321
|
+
subject: ReportSubject;
|
|
322
|
+
receiptId: string;
|
|
323
|
+
receiptDigest: Digest;
|
|
324
|
+
verdict: 'review-ready';
|
|
325
|
+
}
|
|
326
|
+
export interface ReviewTicket {
|
|
327
|
+
id: string;
|
|
328
|
+
requestId: string;
|
|
329
|
+
generation: number;
|
|
330
|
+
subject: ReportSubject;
|
|
331
|
+
validationDigest: Digest;
|
|
332
|
+
/** Digest of the work order frozen at request time. */
|
|
333
|
+
workOrderDigest: Digest;
|
|
334
|
+
}
|
|
335
|
+
export interface ReviewResultV2 {
|
|
336
|
+
ticketId: string;
|
|
337
|
+
requestId: string;
|
|
338
|
+
generation: number;
|
|
339
|
+
subject: ReportSubject;
|
|
340
|
+
terminalEvidenceRef: string;
|
|
341
|
+
decision: 'accept' | 'rework' | 'needs-decision' | 'REVIEW_INCOMPLETE';
|
|
342
|
+
protocolValid: boolean;
|
|
343
|
+
}
|
|
344
|
+
export interface ControlState {
|
|
345
|
+
mode: 'running' | 'paused' | 'stop-requested' | 'cancelled' | 'completed';
|
|
346
|
+
pendingApprovalIds: readonly string[];
|
|
347
|
+
budgetBlocked: boolean;
|
|
348
|
+
recovering: boolean;
|
|
349
|
+
outcomeUnknown: boolean;
|
|
350
|
+
}
|
|
351
|
+
export interface ReviewCompletedPayload {
|
|
352
|
+
decision: 'accept' | 'rework' | 'needs-decision' | 'REVIEW_INCOMPLETE';
|
|
353
|
+
/** Required for a new completion. Decision-only payloads are legacy-unbound. */
|
|
354
|
+
binding?: ReviewResultV2;
|
|
355
|
+
}
|
|
356
|
+
export type FusionEvent = EventEnvelope<'task/created', {
|
|
357
|
+
parent: SessionId;
|
|
358
|
+
selection: RunSelection;
|
|
359
|
+
}> | EventEnvelope<'requirements/revised', {
|
|
360
|
+
reason: string;
|
|
361
|
+
}> | EventEnvelope<'profile/frozen', {
|
|
362
|
+
digest: Digest;
|
|
363
|
+
profileId: string;
|
|
364
|
+
version: string;
|
|
365
|
+
}> | EventEnvelope<'intent/chosen', {
|
|
366
|
+
intent: ExecutionIntent;
|
|
367
|
+
}> | EventEnvelope<'work-order/prepared', {
|
|
368
|
+
order: WorkOrder;
|
|
369
|
+
reservedChild: SessionId;
|
|
370
|
+
}> | EventEnvelope<'work-order/acceptance-amended', {
|
|
371
|
+
workOrderId: WorkOrderId;
|
|
372
|
+
acceptance: readonly AcceptanceCriterion[];
|
|
373
|
+
reason: string;
|
|
374
|
+
}> | EventEnvelope<'work-order/scope-expanded', {
|
|
375
|
+
workOrderId: WorkOrderId;
|
|
376
|
+
allowedPaths: readonly string[];
|
|
377
|
+
added: readonly string[];
|
|
378
|
+
reason: string;
|
|
379
|
+
}> | EventEnvelope<'child/accepted', {
|
|
380
|
+
operationId: OperationId;
|
|
381
|
+
child: SessionId;
|
|
382
|
+
messageId: string;
|
|
383
|
+
}> | EventEnvelope<'child/claimed', {
|
|
384
|
+
operationId: OperationId;
|
|
385
|
+
child: SessionId;
|
|
386
|
+
}> | EventEnvelope<'exploration/recorded', {
|
|
387
|
+
report: ExplorationReport;
|
|
388
|
+
}> | EventEnvelope<'report/submitted', {
|
|
389
|
+
operationId: OperationId;
|
|
390
|
+
report: WorkerReport;
|
|
391
|
+
}> | EventEnvelope<'report/validated', {
|
|
392
|
+
operationId: OperationId;
|
|
393
|
+
report: WorkerReport;
|
|
394
|
+
}> | EventEnvelope<'review/requested', {
|
|
395
|
+
ticket: ReviewTicket;
|
|
396
|
+
}> | EventEnvelope<'review/completed', ReviewCompletedPayload> | EventEnvelope<'lease/acquired', {
|
|
397
|
+
lease: WriteLease;
|
|
398
|
+
}> | EventEnvelope<'lease/released', {
|
|
399
|
+
workspaceId: string;
|
|
400
|
+
generation: number;
|
|
401
|
+
}> | EventEnvelope<'approval/pending', {
|
|
402
|
+
approval: LogicalApproval;
|
|
403
|
+
}> | EventEnvelope<'approval/answered', {
|
|
404
|
+
approvalId: string;
|
|
405
|
+
state: 'approved' | 'rejected' | 'withdrawn';
|
|
406
|
+
}> | EventEnvelope<'budget/blocked', {
|
|
407
|
+
reason: string;
|
|
408
|
+
}> | EventEnvelope<'budget/unblocked', {
|
|
409
|
+
authorizationId: string;
|
|
410
|
+
}> | EventEnvelope<'checkpoint/committed', {
|
|
411
|
+
checkpoint: ContextCheckpoint;
|
|
412
|
+
}> | EventEnvelope<'recovery/needed', {
|
|
413
|
+
reason: string;
|
|
414
|
+
}> | EventEnvelope<'recovery/reconciled', {
|
|
415
|
+
snapshot: SnapshotId;
|
|
416
|
+
evidenceRef: string;
|
|
417
|
+
}> | EventEnvelope<'effect/outcome-unknown', {
|
|
418
|
+
operationId: OperationId;
|
|
419
|
+
reason: string;
|
|
420
|
+
}> | EventEnvelope<'effects/reconciled', {
|
|
421
|
+
snapshot: SnapshotId;
|
|
422
|
+
evidenceRef: string;
|
|
423
|
+
quiescent: true;
|
|
424
|
+
}> | EventEnvelope<'task/stop-requested', {
|
|
425
|
+
intent: 'pause' | 'cancel';
|
|
426
|
+
}> | EventEnvelope<'task/paused', {
|
|
427
|
+
reason: string;
|
|
428
|
+
}> | EventEnvelope<'task/resumed', {
|
|
429
|
+
reason: string;
|
|
430
|
+
}> | EventEnvelope<'task/completed', {
|
|
431
|
+
snapshot: SnapshotId;
|
|
432
|
+
verification: VerificationLevel;
|
|
433
|
+
}> | EventEnvelope<'task/cancelled', {
|
|
434
|
+
reason: string;
|
|
435
|
+
}>;
|
|
436
|
+
export type OutboxState = 'prepared' | 'dispatched' | 'accepted' | 'claimed' | 'result-recorded' | 'delivered' | 'acknowledged';
|
|
437
|
+
export interface OutboxRow {
|
|
438
|
+
operationId: OperationId;
|
|
439
|
+
taskId: TaskId;
|
|
440
|
+
kind: string;
|
|
441
|
+
state: OutboxState;
|
|
442
|
+
reservedChild?: SessionId;
|
|
443
|
+
nativeMessageId?: string;
|
|
444
|
+
resultDigest?: Digest;
|
|
445
|
+
payloadRef?: string;
|
|
446
|
+
requestId?: string;
|
|
447
|
+
ticket?: ReviewTicket;
|
|
448
|
+
}
|
|
449
|
+
export declare const TERMINAL_PHASES: Set<Phase>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Digest } from './contracts.js';
|
|
2
|
+
export declare function sha256Hex(data: string | Uint8Array): Digest;
|
|
3
|
+
export declare function sortKeys(value: unknown): unknown;
|
|
4
|
+
export declare function canonicalJson(value: unknown): string;
|
|
5
|
+
export declare function digestOf(value: unknown): Digest;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import z from '@deepseek-ai/schemastery';
|
|
3
|
+
export * from './index.js';
|
|
4
|
+
export declare const name = "dsh-fusion";
|
|
5
|
+
export declare const inject: string[];
|
|
6
|
+
export interface Config {
|
|
7
|
+
profilePath?: string;
|
|
8
|
+
authorizationPath?: string;
|
|
9
|
+
databasePath?: string;
|
|
10
|
+
workerTools?: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare const Config: z<Config>;
|
|
13
|
+
export declare function apply(ctx: Context, config?: Config): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare class FusionError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
constructor(code: string, message: string);
|
|
4
|
+
}
|
|
5
|
+
export declare const FUSION_CONTEXT_BUDGET = "FUSION_CONTEXT_BUDGET";
|
|
6
|
+
export declare const REVISION_CONFLICT = "REVISION_CONFLICT";
|
|
7
|
+
export declare const REVISION_STALE = "REVISION_STALE";
|
|
8
|
+
export declare const EVENT_CONFLICT = "EVENT_CONFLICT";
|
|
9
|
+
export declare const FLUSH_FAILED = "FLUSH_FAILED";
|
|
10
|
+
export declare const CHECKSUM_MISMATCH = "CHECKSUM_MISMATCH";
|
|
11
|
+
export declare const LEASE_BUSY = "LEASE_BUSY";
|
|
12
|
+
export declare const LEASE_GENERATION = "LEASE_GENERATION";
|
|
13
|
+
export declare const PROFILE_UNAVAILABLE = "PROFILE_UNAVAILABLE";
|
|
14
|
+
export declare const SPEND_UNAUTHORIZED = "SPEND_UNAUTHORIZED";
|
|
15
|
+
export declare const APPROVAL_SCOPE = "APPROVAL_SCOPE";
|
|
16
|
+
export declare const OUTCOME_UNKNOWN = "OUTCOME_UNKNOWN";
|
|
17
|
+
export declare const NEEDS_REPAIR = "NEEDS_REPAIR";
|
|
18
|
+
export declare const USAGE_MERGE_CONFLICT = "USAGE_MERGE_CONFLICT";
|
|
19
|
+
export declare const USAGE_LEDGER_REQUIRED = "USAGE_LEDGER_REQUIRED";
|
|
20
|
+
export declare const CONTROL_BLOCKED = "CONTROL_BLOCKED";
|
|
21
|
+
export declare const REVIEW_RESULT_CONFLICT = "REVIEW_RESULT_CONFLICT";
|
|
22
|
+
export declare const REVIEW_TICKET_REQUIRED = "REVIEW_TICKET_REQUIRED";
|
|
23
|
+
export declare const WORK_ORDER_CONFLICT = "WORK_ORDER_CONFLICT";
|
|
24
|
+
export declare const STORE_MIGRATION_REQUIRED = "STORE_MIGRATION_REQUIRED";
|
|
25
|
+
/** No task carries this id (or it was already deleted). */
|
|
26
|
+
export declare const TASK_NOT_FOUND = "TASK_NOT_FOUND";
|
|
27
|
+
/** Deleting it would strand a live Worker, lease or unfinished handoff. */
|
|
28
|
+
export declare const TASK_BUSY = "TASK_BUSY";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AcceptanceCriterion, Digest, SnapshotId, ToolEvidence, VerificationLevel, WorkOrder, WorkerReport } from '../contracts.js';
|
|
2
|
+
import { type VerificationRegistry } from './receipts.js';
|
|
3
|
+
export interface EvidenceVerdict {
|
|
4
|
+
readonly verification: VerificationLevel;
|
|
5
|
+
readonly reasons: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export type TrustedEvidenceRegistry = readonly ToolEvidence[] | Readonly<Record<string, ToolEvidence>> | ReadonlyMap<string, ToolEvidence>;
|
|
8
|
+
export interface RegisteredVerifier {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly kind: AcceptanceCriterion['verificationKind'];
|
|
11
|
+
readonly argvDigests?: readonly Digest[];
|
|
12
|
+
}
|
|
13
|
+
export interface EvaluateReportOptions {
|
|
14
|
+
readonly verifiers?: readonly RegisteredVerifier[];
|
|
15
|
+
readonly registry?: VerificationRegistry;
|
|
16
|
+
}
|
|
17
|
+
export declare const DEFAULT_TEST_VERIFIERS: readonly RegisteredVerifier[];
|
|
18
|
+
/**
|
|
19
|
+
* Score only the current work order's mandatory criteria and the evidence those
|
|
20
|
+
* claims actually cite. Historical failures stay in the registry for audit.
|
|
21
|
+
* Authenticity and relevance are independent checks.
|
|
22
|
+
*/
|
|
23
|
+
export declare function evaluateReport(workOrder: WorkOrder, report: WorkerReport, trustedRegistry: TrustedEvidenceRegistry, currentSnapshot: SnapshotId, options?: EvaluateReportOptions): EvidenceVerdict;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Digest, SnapshotId, TaskId, ToolEvidence, WorkOrder, WorkOrderId } from '../contracts.js';
|
|
2
|
+
export interface InvocationHeader {
|
|
3
|
+
taskId: ToolEvidence['taskId'];
|
|
4
|
+
workOrderId?: WorkOrderId;
|
|
5
|
+
revision?: number;
|
|
6
|
+
operationId: ToolEvidence['operationId'];
|
|
7
|
+
actor: ToolEvidence['actor'];
|
|
8
|
+
nativeToolCallId: string;
|
|
9
|
+
argvDigest: Digest;
|
|
10
|
+
cwdDigest: Digest;
|
|
11
|
+
inputSnapshot: SnapshotId;
|
|
12
|
+
startedAt: string;
|
|
13
|
+
verifierPlanDigest?: Digest;
|
|
14
|
+
}
|
|
15
|
+
export interface CheckPlan {
|
|
16
|
+
id: string;
|
|
17
|
+
version: number;
|
|
18
|
+
taskId: TaskId;
|
|
19
|
+
workOrderId: WorkOrderId;
|
|
20
|
+
revision: number;
|
|
21
|
+
criterionId: string;
|
|
22
|
+
kind: 'test' | 'static-check' | 'human' | 'review';
|
|
23
|
+
snapshot: SnapshotId;
|
|
24
|
+
/**
|
|
25
|
+
* Version 2 may freeze the verifier before editing. `snapshot` then names the
|
|
26
|
+
* WorkOrder base; native invocation receipts must still bind both input and
|
|
27
|
+
* output to the exact current candidate. Omission retains v1 exact semantics.
|
|
28
|
+
*/
|
|
29
|
+
snapshotBinding?: 'candidate';
|
|
30
|
+
cwdDigest: Digest;
|
|
31
|
+
argvDigest: Digest;
|
|
32
|
+
definitionDigest: Digest;
|
|
33
|
+
policyDigest: Digest;
|
|
34
|
+
minExecutedTests?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Baseline-relative test check: ids that already failed on the untouched workspace, frozen before the
|
|
37
|
+
* Worker started. Only these may fail on the candidate; every other executed test must pass.
|
|
38
|
+
*/
|
|
39
|
+
allowedFailures?: readonly string[];
|
|
40
|
+
}
|
|
41
|
+
export interface PlannedReceipt {
|
|
42
|
+
id: string;
|
|
43
|
+
planDigest: Digest;
|
|
44
|
+
evidence: ToolEvidence;
|
|
45
|
+
counts?: {
|
|
46
|
+
executed: number;
|
|
47
|
+
passed: number;
|
|
48
|
+
failed: number;
|
|
49
|
+
/** Failures frozen in the plan's baseline (not counted as executed). */
|
|
50
|
+
knownFailures?: readonly string[];
|
|
51
|
+
/** Failures absent from the baseline; counted in `failed`. */
|
|
52
|
+
newFailures?: readonly string[];
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export interface VerificationRegistry {
|
|
56
|
+
getPlan(planId: string): CheckPlan | undefined;
|
|
57
|
+
getReceipt(receiptId: string): PlannedReceipt | undefined;
|
|
58
|
+
}
|
|
59
|
+
export declare function memoryVerificationRegistry(plans: readonly CheckPlan[], receipts: readonly PlannedReceipt[]): VerificationRegistry;
|
|
60
|
+
export declare function assertPlannedCheck(workOrder: WorkOrder, criterionId: string, plan: CheckPlan, receipt: PlannedReceipt, actualSnapshot: SnapshotId): void;
|
|
61
|
+
export declare function invocationHeader(record: ToolEvidence, extras?: Partial<InvocationHeader>): InvocationHeader;
|
|
62
|
+
export declare function sameInvocationHeader(left: InvocationHeader, right: InvocationHeader): boolean;
|
|
63
|
+
export declare function artifactFingerprint(ref: ToolEvidence['stdout']): string;
|
|
64
|
+
export declare function resolveInvocation(records: readonly ToolEvidence[]): ToolEvidence;
|
|
65
|
+
export declare function checkPlanDigest(plan: CheckPlan): Digest;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { OperationId, SessionId, TaskId, WriteLease } from '../contracts.js';
|
|
2
|
+
export interface LeaseRecord extends WriteLease {
|
|
3
|
+
readonly owner: string;
|
|
4
|
+
readonly pid: number;
|
|
5
|
+
readonly acquiredAt: string;
|
|
6
|
+
readonly liveProcessRefs: readonly number[];
|
|
7
|
+
}
|
|
8
|
+
export declare function canonicalWorkspace(cwd: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Move a pre-rename lease registry to its current name.
|
|
11
|
+
*
|
|
12
|
+
* The registry outlives a single process, so a rename must carry it: a fresh
|
|
13
|
+
* empty directory beside a lock nobody reads would report the workspace as
|
|
14
|
+
* free while a previous holder believes it still owns the write lease. A move
|
|
15
|
+
* keeps that holder visible to the next process; a cross-device install copies
|
|
16
|
+
* the directory instead, and a failed copy removes only what it created.
|
|
17
|
+
*
|
|
18
|
+
* @param next - registry directory the current release uses.
|
|
19
|
+
* @param legacy - registry directory the previous name used.
|
|
20
|
+
* @returns whether a legacy registry was adopted.
|
|
21
|
+
*/
|
|
22
|
+
export declare function adoptLegacyLeaseRoot(next: string, legacy?: string): boolean;
|
|
23
|
+
export declare function leasePath(workspaceId: string, root?: string): string;
|
|
24
|
+
export declare class WorkspaceWriteLease {
|
|
25
|
+
#private;
|
|
26
|
+
private readonly root;
|
|
27
|
+
constructor(root?: string);
|
|
28
|
+
acquire(input: {
|
|
29
|
+
cwd: string;
|
|
30
|
+
holder: SessionId;
|
|
31
|
+
taskId: TaskId;
|
|
32
|
+
operationId: OperationId;
|
|
33
|
+
liveProcessRefs?: readonly number[];
|
|
34
|
+
}): LeaseRecord;
|
|
35
|
+
assertGeneration(lease: WriteLease, generation: number): void;
|
|
36
|
+
stillHeld(lease: LeaseRecord): boolean;
|
|
37
|
+
/** Caller must prove native Worker/tool quiescence before releasing. */
|
|
38
|
+
release(lease: LeaseRecord): void;
|
|
39
|
+
/** Trusted recovery inspection. A dead PID by itself never authorizes stealing. */
|
|
40
|
+
current(cwd: string): LeaseRecord | undefined;
|
|
41
|
+
}
|
|
42
|
+
export declare function classifyEffect(kind: 'read-tool' | 'write-tool' | 'unknown-shell'): 'read' | 'write';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PairProfile, TaskId } from '../contracts.js';
|
|
2
|
+
import type { PromptBundle, ResolvedProfile } from '../profile/resolve.js';
|
|
3
|
+
import type { SqliteFusionStore } from '../task/sqlite-store.js';
|
|
4
|
+
export interface SessionBinding {
|
|
5
|
+
readonly schemaVersion: 1;
|
|
6
|
+
readonly sessionId: string;
|
|
7
|
+
readonly taskId: TaskId;
|
|
8
|
+
readonly selected: boolean;
|
|
9
|
+
/** One native continuable Worker for this selection, across completed tasks. */
|
|
10
|
+
readonly workerId?: string;
|
|
11
|
+
readonly profile: PairProfile;
|
|
12
|
+
readonly prompts: PromptBundle;
|
|
13
|
+
}
|
|
14
|
+
export declare function readBinding(value: unknown, sessionId: string): SessionBinding;
|
|
15
|
+
/** Selection is durable and scoped by the native Lead identity, never a global default. */
|
|
16
|
+
export declare class BindingRepository {
|
|
17
|
+
private readonly store;
|
|
18
|
+
constructor(store: SqliteFusionStore);
|
|
19
|
+
read(sessionId: string): {
|
|
20
|
+
revision: number;
|
|
21
|
+
binding: SessionBinding;
|
|
22
|
+
} | undefined;
|
|
23
|
+
select(sessionId: string, id: TaskId, resolved: ResolvedProfile): SessionBinding;
|
|
24
|
+
clear(sessionId: string): void;
|
|
25
|
+
/** Reserve identity before native dispatch; an existing selection cannot swap workers. */
|
|
26
|
+
assignWorker(sessionId: string, expectedTask: TaskId, workerId: string): void;
|
|
27
|
+
/** A new native user turn starts a new task while preserving the frozen pair. */
|
|
28
|
+
rollover(sessionId: string, expectedTask: TaskId, nextTask: TaskId): SessionBinding;
|
|
29
|
+
selected(): readonly SessionBinding[];
|
|
30
|
+
}
|