dsh-kingdom 2.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/ASSETS_NOTICE.md +22 -22
  2. package/README.md +244 -243
  3. package/THIRD_PARTY_NOTICES.md +92 -92
  4. package/docs/DSH-KINGDOM-3.0-ANNOUNCEMENT.md +13 -0
  5. package/docs/V2.0-RELEASE-NOTES.md +30 -30
  6. package/docs/V2.0-USER-GUIDE.md +74 -74
  7. package/docs/V3.0-RELEASE-NOTES.md +21 -0
  8. package/docs/V3.0-USER-GUIDE.md +33 -0
  9. package/docs/V3.1-RELEASE-NOTES.md +72 -0
  10. package/lib/core/binding.js +2 -0
  11. package/lib/core/binding.js.map +1 -1
  12. package/lib/core/db.js +546 -546
  13. package/lib/core/delivery-ack.js +1356 -0
  14. package/lib/core/delivery-ack.js.map +1 -0
  15. package/lib/core/delivery-change.js +1237 -0
  16. package/lib/core/delivery-change.js.map +1 -0
  17. package/lib/core/owner-window.js +592 -11
  18. package/lib/core/owner-window.js.map +1 -1
  19. package/lib/core/task-service.js +144 -5
  20. package/lib/core/task-service.js.map +1 -1
  21. package/lib/gui/assets/characters/chancellor-idle.svg +67 -67
  22. package/lib/gui/assets/characters/chancellor-sleeping.svg +67 -67
  23. package/lib/gui/assets/characters/chancellor-thinking.svg +67 -67
  24. package/lib/gui/assets/characters/chancellor-working.svg +67 -67
  25. package/lib/gui/assets/characters/knight-redraw-r1-idle.svg +67 -67
  26. package/lib/gui/assets/characters/knight-redraw-r1-sleeping.svg +67 -67
  27. package/lib/gui/assets/characters/knight-redraw-r1-thinking.svg +67 -67
  28. package/lib/gui/assets/characters/knight-redraw-r1-working.svg +67 -67
  29. package/lib/gui/assets/characters/supervisor-idle.svg +67 -67
  30. package/lib/gui/assets/characters/supervisor-sleeping.svg +67 -67
  31. package/lib/gui/assets/characters/supervisor-thinking.svg +67 -67
  32. package/lib/gui/assets/characters/supervisor-working.svg +67 -67
  33. package/lib/gui/console-app.js +7 -1
  34. package/lib/gui/console-app.js.map +1 -1
  35. package/lib/gui/contract.js +6 -0
  36. package/lib/gui/contract.js.map +1 -1
  37. package/lib/gui/owner-control.js +114 -4
  38. package/lib/gui/owner-control.js.map +1 -1
  39. package/lib/gui/owner-ui.js +604 -183
  40. package/lib/gui/owner-ui.js.map +1 -1
  41. package/lib/gui/server.js +109 -109
  42. package/lib/gui/snapshot.js +127 -4
  43. package/lib/gui/snapshot.js.map +1 -1
  44. package/lib/gui/visual-assets.js +37 -21
  45. package/lib/gui/visual-assets.js.map +1 -1
  46. package/lib/gui/visual-system.js +269 -269
  47. package/lib/gui/workbench-ui.js +537 -136
  48. package/lib/gui/workbench-ui.js.map +1 -1
  49. package/lib/gui/workbench.js +123 -0
  50. package/lib/gui/workbench.js.map +1 -1
  51. package/lib/index.js +338 -26
  52. package/lib/index.js.map +1 -1
  53. package/lib/types/core/binding.d.ts +15 -0
  54. package/lib/types/core/delivery-ack.d.ts +688 -0
  55. package/lib/types/core/delivery-change.d.ts +381 -0
  56. package/lib/types/core/owner-window.d.ts +235 -2
  57. package/lib/types/core/task-service.d.ts +22 -0
  58. package/lib/types/gui/contract.d.ts +153 -1
  59. package/lib/types/gui/owner-control.d.ts +61 -1
  60. package/lib/types/gui/snapshot.d.ts +8 -0
  61. package/lib/types/gui/visual-assets.d.ts +16 -0
  62. package/lib/types/gui/workbench.d.ts +47 -1
  63. package/lib/types/index.d.ts +49 -0
  64. package/lib/types/worker/governed-executor.d.ts +15 -0
  65. package/lib/worker/governed-executor.js +21 -0
  66. package/lib/worker/governed-executor.js.map +1 -1
  67. package/package.json +79 -75
@@ -0,0 +1,381 @@
1
+ import type { EventRow, KingdomStore } from './db.js';
2
+ import { CHANGE_EVIDENCE_LABEL, CHANGE_EVIDENCE_NOTE } from './delivery-ack.js';
3
+ export { CHANGE_EVIDENCE_LABEL, CHANGE_EVIDENCE_NOTE };
4
+ export declare const DELIVERY_CHANGE_SNAPSHOT_EVENT_TYPE = "DELIVERY_CHANGE_SNAPSHOT";
5
+ export declare const DELIVERY_CHANGE_MANIFEST_VERSION = "KingdomDeliveryChangeManifest/v1";
6
+ export declare const DELIVERY_CHANGE_SNAPSHOT_VERSION = "KingdomDeliveryWorkspaceSnapshot/v1";
7
+ export declare const CHANGE_EVIDENCE_DRIFT = "\u8BC1\u636E\u6B63\u6587\u7F3A\u5931\u6216\u54C8\u5E0C\u6F02\u79FB\uFF0C\u4E0D\u80FD\u4F5C\u4E3A\u53EF\u4FE1\u6539\u52A8\u5B9A\u4F4D\u3002";
8
+ /** 采集与分析的有界上限;任何一项被触发都会如实反映为部分覆盖。 */
9
+ export interface DeliveryChangeBounds {
10
+ maxFiles: number;
11
+ maxFileBytes: number;
12
+ /**
13
+ * 单个文件的**完整内容 hash**上限;超过即无法完整比较,只能如实记 `UNKNOWN`,
14
+ * 不得用「真实大小 + 有界首段」的前缀摘要冒充完整内容 hash。
15
+ */
16
+ maxHashBytes: number;
17
+ /** 单次采集允许读取的总字节数;超出后不再读取,未比较的文件必须如实计入部分覆盖。 */
18
+ maxReadBytes: number;
19
+ maxStoredBytes: number;
20
+ maxDiffLines: number;
21
+ maxEntries: number;
22
+ /** Git 候选枚举的字节上限;超出即视为无法安全枚举,如实报失败而不是截断成「无改动」。 */
23
+ maxCandidateBytes: number;
24
+ /** VCS 忽略样本的字节上限;只用于报告有多少内容被 ignore 规则排除,不读取其正文。 */
25
+ maxIgnoredBytes: number;
26
+ }
27
+ export declare const DEFAULT_DELIVERY_CHANGE_BOUNDS: DeliveryChangeBounds;
28
+ export type DeliveryChangePhase = 'PRE' | 'POST';
29
+ /**
30
+ * `UNKNOWN` 只用于「无法证明是否变化」的候选:内容过长/不可读/是符号链接导致
31
+ * 比较不可靠。它**不是**可由主管确认的改动条目,选择它会被拒绝。
32
+ */
33
+ export type DeliveryChangeStatus = 'ADDED' | 'MODIFIED' | 'DELETED' | 'UNKNOWN';
34
+ export type DeliveryChangeEvidenceKind = 'SUPERVISOR_CONFIRMED_BOUNDED_WINDOW';
35
+ export interface DeliverySnapshotCoverage {
36
+ complete: boolean;
37
+ observedFiles: number;
38
+ retainedFiles: number;
39
+ /** 因上限被跳过的条目数下界;达到文件或读取预算上限后不再继续读取。 */
40
+ omittedByLimit: number;
41
+ /** 采集时无法读取、因此无法证明是否变化的候选数。 */
42
+ omittedUnreadable: number;
43
+ skippedSymlinks: number;
44
+ skippedOversize: number;
45
+ binaryFiles: number;
46
+ /** 检测到 PEM 私钥/证书标记、因而**不保留正文**的候选数(只保留摘要)。 */
47
+ sensitiveBodiesSkipped: number;
48
+ /**
49
+ * 被 VCS ignore 规则排除、因而从未成为候选的路径数(只计数与保留路径名样本)。
50
+ *
51
+ * 这是**有意**的范围限定:候选集合本身完整、只是不含被忽略内容,所以它只让
52
+ * `complete=false`,**不**使未忽略路径的「不在快照里 = 当时不存在」失效。
53
+ */
54
+ ignoredPaths: number;
55
+ /** 证据目录位于工作区内时被有意排除的路径数(避免把自身快照算成改动),同理不推断枚举被截断。 */
56
+ evidenceRootExcluded: number;
57
+ reasons: string[];
58
+ /** 被 VCS ignore 规则排除的路径名样本;只保留路径,不含正文。 */
59
+ ignoredSamples: string[];
60
+ }
61
+ export type DeliveryFileReadability = 'READABLE' | 'ABSENT' | 'UNREADABLE' | 'SYMLINK';
62
+ export interface DeliveryWorkspaceFileObservation {
63
+ /** 工作区内采集用的规范化相对路径;仅用于本地读取与条目身份,不直接作为公开展示路径。 */
64
+ path: string;
65
+ /** 仓库相对路径;Owner 展示、主管候选与「查看改动」一律使用这一路径。 */
66
+ repoPath: string | null;
67
+ size: number;
68
+ binary: boolean;
69
+ symlink: boolean;
70
+ oversize: boolean;
71
+ /**
72
+ * 是否命中 PEM 私钥/证书标记、因而**不保留正文**。两侧任一为 `true` 时差异条目
73
+ * 都不展示正文片段:否则未命中一侧的历史正文会把另一侧的主体带进公开视图。
74
+ */
75
+ sensitive: boolean;
76
+ /** 是否把脱敏后的正文写入了内容寻址 blob(两侧都保留,便于展示增删片段)。 */
77
+ retained: boolean;
78
+ /** 完整内容摘要;无法完整读取(超限/部分读取)时为 null,绝不退化成前缀摘要。 */
79
+ rawHash: string | null;
80
+ storedHash: string | null;
81
+ /** 采集时刻该路径的 `git status --porcelain` 代码;无 VCS 时为 null。 */
82
+ vcs: string | null;
83
+ /** 本次采集对该路径的实际可读性判定;决定差异能否被证明。 */
84
+ readability: DeliveryFileReadability;
85
+ }
86
+ export interface DeliveryRepoIdentity {
87
+ vcs: 'GIT' | 'UNAVAILABLE';
88
+ /** 仓库身份的不可逆摘要,避免证据里出现本机绝对路径。 */
89
+ identity: string | null;
90
+ head: string | null;
91
+ scope: 'REPO_ROOT' | 'WORKSPACE_SUBDIR' | 'OUTSIDE_REPO' | 'UNKNOWN';
92
+ reason: string | null;
93
+ }
94
+ export interface DeliveryWorkspaceSnapshot {
95
+ version: typeof DELIVERY_CHANGE_SNAPSHOT_VERSION;
96
+ snapshotId: string;
97
+ phase: DeliveryChangePhase;
98
+ taskId: string;
99
+ attemptNo: number;
100
+ territoryId: string;
101
+ workspaceKey: string;
102
+ executionId: string | null;
103
+ leaseId: string | null;
104
+ dispatchId: string | null;
105
+ repo: DeliveryRepoIdentity;
106
+ capturedAt: string;
107
+ files: DeliveryWorkspaceFileObservation[];
108
+ coverage: DeliverySnapshotCoverage;
109
+ /** 候选枚举本身的有界元数据(不含正文):便于区分「无改动」与「没能枚举完整」。 */
110
+ candidateScope: {
111
+ kind: 'VCS_CANDIDATES';
112
+ candidateCount: number;
113
+ pathspec: string;
114
+ evidencePrefix: string | null;
115
+ evidenceRootExcluded: number;
116
+ };
117
+ /**
118
+ * 该时刻的候选集合是否**完整可信**:本快照里「没有该路径」是否可以当成「它当时不存在」。
119
+ *
120
+ * 只有下列条件同时成立才为 `true`:候选枚举未被文件/读取预算截断,也没有读不出来的候选。
121
+ *
122
+ * `.gitignore` 排除的内容与证据目录自身是**有意**待在候选集合之外的范围限定:候选
123
+ * 枚举本身是完整的,因此它们只如实记为部分覆盖(`coverage.reasons`),**不**推断
124
+ * 「未忽略路径的存在性不可证明」。把有意排除当成枚举截断会让真实新增无法确认。
125
+ */
126
+ enumerationComplete: boolean;
127
+ /**
128
+ * 被 ignore 规则排除的路径身份(工作区相对);只含路径名,不含任何正文。
129
+ *
130
+ * 增删判定不只看「该路径在不在快照里」,还要看它是否出现在**另一时点**的这份身份
131
+ * 集合中:只改忽略规则时,内容未变的旧文件会离开或进入候选集合,那个缺项其实是被
132
+ * ignore,既不是窗口内新增也不是窗口内删除。
133
+ */
134
+ ignoredPathIdentities: string[];
135
+ /**
136
+ * 上述身份集合是否完整可信(枚举未被字节上限截断)。
137
+ *
138
+ * `false` 时不得把「路径不在集合里」当成「它当时未被忽略」:增删判定必须 fail-closed,
139
+ * 否则无法排除「另一个时点其实被 ignore」这一可能。
140
+ */
141
+ ignoredPathsComplete: boolean;
142
+ }
143
+ export interface DeliveryChangeHunk {
144
+ kind: 'ADDED' | 'REMOVED';
145
+ beforeLine: number | null;
146
+ afterLine: number | null;
147
+ text: string;
148
+ }
149
+ export interface DeliveryChangeEntry {
150
+ entryId: string;
151
+ /** 工作区相对路径;本地读取与身份用,不作为公开展示路径。 */
152
+ path: string;
153
+ /** 仓库相对路径(Owner 详情、主管候选与工作台固定展示这一条)。 */
154
+ repoPath: string;
155
+ status: DeliveryChangeStatus;
156
+ reasonCode: string;
157
+ labels: string[];
158
+ note: string;
159
+ binary: boolean;
160
+ bodyRetained: boolean;
161
+ beforeHash: string | null;
162
+ afterHash: string | null;
163
+ /** 基线正文未保留(预算/二进制/超限)时无法展示删除片段。 */
164
+ baselineBodyUnavailable: boolean;
165
+ hunks: DeliveryChangeHunk[];
166
+ }
167
+ export interface DeliveryChangeManifest {
168
+ version: typeof DELIVERY_CHANGE_MANIFEST_VERSION;
169
+ evidenceId: string;
170
+ taskId: string;
171
+ attemptNo: number;
172
+ territoryId: string;
173
+ workspaceKey: string;
174
+ repo: DeliveryRepoIdentity;
175
+ executionId: string | null;
176
+ leaseId: string | null;
177
+ dispatchId: string | null;
178
+ pre: {
179
+ snapshotId: string;
180
+ capturedAt: string;
181
+ coverage: DeliverySnapshotCoverage;
182
+ };
183
+ post: {
184
+ snapshotId: string;
185
+ capturedAt: string;
186
+ coverage: DeliverySnapshotCoverage;
187
+ };
188
+ entries: DeliveryChangeEntry[];
189
+ coverage: {
190
+ complete: boolean;
191
+ reasons: string[];
192
+ entryCount: number;
193
+ omitted: number;
194
+ };
195
+ note: string;
196
+ createdAt: string;
197
+ }
198
+ /** 主管 ACCEPT 时显式选中的改动引用(写入 TASK_ACCEPTED payload)。 */
199
+ export interface DeliveryChangeEvidenceRef {
200
+ kind: DeliveryChangeEvidenceKind;
201
+ evidenceId: string;
202
+ attemptNo: number;
203
+ entryIds: string[];
204
+ selectionDigest: string;
205
+ entryCount: number;
206
+ selectedCount: number;
207
+ coverageComplete: boolean;
208
+ coverageReasons: string[];
209
+ repoHead: string | null;
210
+ note: string;
211
+ }
212
+ export interface DeliveryEvidencePaths {
213
+ root: string;
214
+ snapshots: string;
215
+ blobs: string;
216
+ manifests: string;
217
+ }
218
+ /**
219
+ * 交付改动证据的专用本机持久目录:<dshHome>/kingdom/delivery-evidence。
220
+ *
221
+ * 只保存有界、脱敏、内容寻址的快照与差异;不接触 kingdom.db 本身。
222
+ * `DSH_KINGDOM_EVIDENCE_ROOT` 只用于把测试指向一次性临时目录。
223
+ */
224
+ export declare function deliveryEvidenceRoot(): string;
225
+ export declare function deliveryEvidencePaths(evidenceRoot?: string): DeliveryEvidencePaths;
226
+ export declare function readChangeBlob(evidenceRoot: string | undefined, storedHash: string): string | null;
227
+ export type CaptureSnapshotResult = {
228
+ ok: true;
229
+ snapshot: DeliveryWorkspaceSnapshot;
230
+ snapshotFile: string;
231
+ } | {
232
+ ok: false;
233
+ code: string;
234
+ reason: string;
235
+ };
236
+ export interface CaptureSnapshotInput {
237
+ workspacePath: string;
238
+ taskId: string;
239
+ attemptNo: number;
240
+ territoryId: string;
241
+ phase: DeliveryChangePhase;
242
+ executionId?: string | null;
243
+ leaseId?: string | null;
244
+ dispatchId?: string | null;
245
+ evidenceRoot?: string;
246
+ bounds?: Partial<DeliveryChangeBounds>;
247
+ now?: string;
248
+ }
249
+ /**
250
+ * 冻结一份有界工作区快照。**永不抛出**:采集失败只返回 `ok:false`,
251
+ * 调用方据此不产生任何改动链接,而不是把失败伪装成空差异。
252
+ *
253
+ * 候选路径全部来自 Git(见 {@link enumerateCandidates}):没有可用的 Git 基准、
254
+ * 枚举失败或输出超限时直接返回失败,绝不退化成「扫描任意工作区正文」。
255
+ */
256
+ export declare function captureWorkspaceSnapshot(input: CaptureSnapshotInput): CaptureSnapshotResult;
257
+ export declare function readWorkspaceSnapshot(evidenceRoot: string | undefined, snapshotId: string): DeliveryWorkspaceSnapshot | null;
258
+ export declare function deliveryChangeEvidenceId(manifest: DeliveryChangeManifest): string;
259
+ export type BuildChangeManifestResult = {
260
+ ok: true;
261
+ manifest: DeliveryChangeManifest;
262
+ file: string;
263
+ } | {
264
+ ok: false;
265
+ code: string;
266
+ reason: string;
267
+ };
268
+ /** 采集执行前的有界基线;失败返回 null(调用方不得伪造空差异)。 */
269
+ export declare function capturePreChangeSnapshot(input: Omit<CaptureSnapshotInput, 'phase'>): DeliveryWorkspaceSnapshot | null;
270
+ export interface CompleteChangeManifestInput {
271
+ workspacePath: string;
272
+ pre: DeliveryWorkspaceSnapshot;
273
+ taskId: string;
274
+ attemptNo: number;
275
+ territoryId: string;
276
+ executionId?: string | null;
277
+ leaseId?: string | null;
278
+ dispatchId?: string | null;
279
+ evidenceRoot?: string;
280
+ bounds?: Partial<DeliveryChangeBounds>;
281
+ }
282
+ /**
283
+ * terminal / WorkerResult 之前采集 POST 并生成差异 manifest。
284
+ *
285
+ * 采集或写入任一步失败都返回 null:宁可没有改动定位,也不产生不可信的链接。
286
+ */
287
+ export declare function capturePostAndBuildChangeManifest(input: CompleteChangeManifestInput): DeliveryChangeManifest | null;
288
+ export interface BuildChangeManifestInput {
289
+ evidenceRoot?: string;
290
+ pre: DeliveryWorkspaceSnapshot;
291
+ post: DeliveryWorkspaceSnapshot;
292
+ bounds?: Partial<DeliveryChangeBounds>;
293
+ resultRef?: string | null;
294
+ now?: string;
295
+ }
296
+ /** 由 PRE/POST 两份快照生成有界、脱敏的差异 manifest,并原子写入内容寻址文件。 */
297
+ export declare function buildDeliveryChangeManifest(input: BuildChangeManifestInput): BuildChangeManifestResult;
298
+ /** 有界行级差异:裁掉公共前后缀后,把中段如实标成 REMOVED/ADDED 片段。 */
299
+ export declare function diffLines(before: string, after: string, maxLines: number): DeliveryChangeHunk[];
300
+ export type VerifyChangeManifestResult = {
301
+ ok: true;
302
+ manifest: DeliveryChangeManifest;
303
+ } | {
304
+ ok: false;
305
+ code: string;
306
+ reason: string;
307
+ };
308
+ /** 读回并按内容寻址重验 manifest 与保留正文的 hash;漂移即不可用。 */
309
+ export declare function verifyChangeManifest(evidenceRoot: string | undefined, evidenceId: string): VerifyChangeManifestResult;
310
+ /** 读取由主管 ACCEPT 绑定在该 Task 上的改动证据引用。 */
311
+ export declare function readAcceptedChangeEvidence(review: EventRow | null): DeliveryChangeEvidenceRef | null;
312
+ export declare function selectionDigest(entryIds: readonly string[]): string;
313
+ /**
314
+ * 校验主管显式选择:evidence 必须存在且 hash 一致,选中的 entry 必须真实存在。
315
+ * 任一失败都返回错误,调用方必须拒绝并零写入。
316
+ */
317
+ export declare function validateChangeSelection(evidenceRoot: string | undefined, manifest: DeliveryChangeManifest, entryIds: readonly string[], expected: {
318
+ taskId: string;
319
+ attemptNo: number;
320
+ }): {
321
+ ok: true;
322
+ ref: DeliveryChangeEvidenceRef;
323
+ } | {
324
+ ok: false;
325
+ code: string;
326
+ reason: string;
327
+ };
328
+ /** 事件载荷:只含 task/attempt/result、manifest/hash 与有界元数据,不含仓库正文。 */
329
+ export declare function changeSnapshotEventPayload(manifest: DeliveryChangeManifest, resultRef: string | null): Record<string, unknown>;
330
+ export declare function changeSnapshotEventId(kingdomId: string, taskId: string, attemptNo: number, executionRef: string | null): string;
331
+ /** Territory canonical workspace 的不可逆摘要,用于把快照绑定到具体领地工作区。 */
332
+ export declare function workspaceKeyOf(workspacePath: string): string | null;
333
+ export interface ChangeSnapshotEventRef {
334
+ event: EventRow;
335
+ evidenceId: string;
336
+ attemptNo: number;
337
+ resultId: string | null;
338
+ executionId: string | null;
339
+ coverageComplete: boolean;
340
+ coverageReasons: string[];
341
+ }
342
+ /** 精确读取某 Task/attempt 的改动快照事件(不走有界 GUI 投影)。 */
343
+ export declare function readChangeSnapshotEvent(store: KingdomStore, kingdomId: string, taskId: string, attemptNo: number): ChangeSnapshotEventRef | null;
344
+ /** 主管候选清单用的有界条目视图(只读,不写任何事实);展示路径是仓库相对路径。 */
345
+ export declare function listChangeEntries(manifest: DeliveryChangeManifest, limit?: number): {
346
+ entryId: string;
347
+ repoPath: string;
348
+ status: string;
349
+ note: string;
350
+ }[];
351
+ /** 读回一条已确认改动条目的有界视图:只按 entry id 取,不接受任意路径。 */
352
+ export declare function readChangeEntry(evidenceRoot: string | undefined, ref: DeliveryChangeEvidenceRef, entryId: string): {
353
+ ok: true;
354
+ entry: DeliveryChangeEntry;
355
+ manifest: DeliveryChangeManifest;
356
+ } | {
357
+ ok: false;
358
+ code: string;
359
+ reason: string;
360
+ };
361
+ /** 交付条目派生用的已解析证据形状(与 `delivery-ack.ts` 的结构一致)。 */
362
+ export interface ResolvedChangeEvidence {
363
+ evidenceId: string;
364
+ attemptNo: number;
365
+ repoHead: string | null;
366
+ coverageComplete: boolean;
367
+ coverageReasons: string[];
368
+ note: string;
369
+ /** 条目展示路径一律是仓库相对路径。 */
370
+ entries: {
371
+ entryId: string;
372
+ repoPath: string;
373
+ status: string;
374
+ note: string;
375
+ }[];
376
+ }
377
+ /**
378
+ * 把已确认的改动引用解析成可投影条目。任何 hash 漂移或正文缺失都返回 null,
379
+ * 调用方据此显示「不可定位」,而不是继续用可能被替换的正文。
380
+ */
381
+ export declare function resolveChangeEvidenceForDelivery(evidenceRoot: string | undefined, ref: DeliveryChangeEvidenceRef): ResolvedChangeEvidence | null;
@@ -3,7 +3,8 @@ import { type ExecutionProfileV1 } from './binding.js';
3
3
  import { type OwnerControlCapability } from './owner-control.js';
4
4
  import { type BudgetPolicyParameters } from './budget.js';
5
5
  import { type PlanAdoptionParameters, type CollaborationPlanView } from './collaboration.js';
6
- export declare const OWNER_MUTATION_ACTIONS: readonly ["init", "territory.create", "territory.update", "territory.supervisor", "role.bind", "role.session", "ceiling", "execution-profile", "budget.policy", "plan.adopt"];
6
+ import { type DeliveryAcceptanceEvidenceKind, type DeliveryItemVersionState, type DeliveryReplyState } from './delivery-ack.js';
7
+ export declare const OWNER_MUTATION_ACTIONS: readonly ["init", "territory.create", "territory.update", "territory.supervisor", "role.bind", "role.session", "ceiling", "execution-profile", "budget.policy", "plan.adopt", "delivery.item.ack", "delivery.item.question"];
7
8
  export type OwnerMutationAction = typeof OWNER_MUTATION_ACTIONS[number];
8
9
  export type OwnerManagedRole = 'CHANCELLOR' | 'SUPERVISOR' | 'WORKER';
9
10
  export interface OwnerDecisionScope {
@@ -60,6 +61,148 @@ export interface OwnerRuntimeSessionChoice {
60
61
  id: string;
61
62
  label: string;
62
63
  }
64
+ /** 交付清单条目:只有已被主管 ACCEPT 确认的交付才会出现。 */
65
+ export interface OwnerDeliveryItemChoice {
66
+ taskId: string;
67
+ taskTitle: string;
68
+ deliveryId: string;
69
+ attemptNo: number;
70
+ resultId: string;
71
+ itemId: string;
72
+ contentHash: string;
73
+ layer: string;
74
+ label: string;
75
+ detail: string;
76
+ changeKind: string;
77
+ changeNote: string;
78
+ acknowledgementState: 'ACKNOWLEDGED' | 'PENDING' | 'PENDING_REVISION';
79
+ acknowledgedAt: string | null;
80
+ /**
81
+ * 本次确认交付实际依据的接受证据强度。`LEGACY_ATTEMPT_ONLY` 时
82
+ * `acceptanceEvidenceNote` 必须原样展示给 Owner(历史接受证据较弱),
83
+ * 且不得把它当作 exact result-bound。
84
+ */
85
+ acceptanceEvidenceKind: DeliveryAcceptanceEvidenceKind;
86
+ acceptanceEvidenceExact: boolean;
87
+ acceptanceEvidenceNote: string | null;
88
+ /**
89
+ * 该条目已有的 Owner 提问元数据(不含正文)。正文只经
90
+ * {@link OwnerDecisionController.readDeliveryQuestions} 在有效窗口内按精确条目返回。
91
+ */
92
+ questions: OwnerDeliveryItemQuestions | null;
93
+ }
94
+ /** 条目提问的**元数据**:不含问题或回复正文。 */
95
+ export interface OwnerDeliveryItemQuestions {
96
+ threadId: string;
97
+ totalCount: number;
98
+ /** 主管尚未回复的问题数;未被实际读取前只算「待领取」。 */
99
+ pendingCount: number;
100
+ answeredCount: number;
101
+ /** 属于旧内容版本、仅留历史的问题数。 */
102
+ historyCount: number;
103
+ lastAskedAt: string | null;
104
+ lastRepliedAt: string | null;
105
+ /** 最近一条问题的接收主管是否仍可回复;不可达时界面必须照实说明。 */
106
+ latestReplyState: DeliveryReplyState | null;
107
+ }
108
+ /**
109
+ * Owner 只读问答历史入口的一条精确条目(不含问题或回复正文)。
110
+ *
111
+ * 与 `deliveryItems` 分开:它只来自既有提问事实,因此包含已经离开当前交付目录、
112
+ * 目前无法重验的旧问答。它只供只读回看,**绝不**作为新提问目标;新提问仍须落在
113
+ * 当前已确认交付目录内并逐条精确重验。
114
+ */
115
+ export interface OwnerDeliveryQuestionHistoryChoice {
116
+ taskId: string;
117
+ taskTitle: string;
118
+ itemId: string;
119
+ itemLabel: string;
120
+ lastAskedAt: string;
121
+ questionCount: number;
122
+ /** 已验证当前版本且尚无回复的条数;历史版与无法重验的都不计入。 */
123
+ pendingCount: number;
124
+ answeredCount: number;
125
+ historyCount: number;
126
+ unverifiableCount: number;
127
+ latestItemVersion: DeliveryItemVersionState;
128
+ currentContentHash: string | null;
129
+ }
130
+ /**
131
+ * Owner 只读的条目问答线程。
132
+ *
133
+ * 与「查看改动」同款边界:只经有效 Owner 窗口、精确条目引用与本次动作授权返回,
134
+ * **读取不写任何事实**、不自动知悉、也不替主管回复。
135
+ */
136
+ export interface OwnerDeliveryQuestionEntry {
137
+ questionId: string;
138
+ questionText: string;
139
+ askedAt: string;
140
+ ownerId: string;
141
+ /** 接受该交付的主管 binding;首版唯一合法接收者。 */
142
+ reviewerBindingId: string;
143
+ replyState: DeliveryReplyState;
144
+ replyStateNote: string;
145
+ /**
146
+ * 该问题相对当前交付目录的版本关系:已验证当前、可确认的旧版本,或无法重验。
147
+ * 后两者仍可读、仍保留原文与回复,但**不计当前待办**,界面也不得据此声称
148
+ * 「当前可回复」。
149
+ */
150
+ itemVersion: DeliveryItemVersionState;
151
+ /** 当前读取时该条目重新派生出的内容版本;无法派生时为 null。 */
152
+ currentItemContentHash: string | null;
153
+ reply: {
154
+ replyText: string;
155
+ repliedAt: string;
156
+ responderBindingId: string;
157
+ } | null;
158
+ }
159
+ export interface OwnerDeliveryQuestionView {
160
+ deliveryId: string;
161
+ taskId: string;
162
+ taskTitle: string;
163
+ itemId: string;
164
+ itemLabel: string;
165
+ /** 本次读取时该条目的当前内容版本;无法在当前交付目录中重验时为 null。 */
166
+ contentHash: string | null;
167
+ questions: OwnerDeliveryQuestionEntry[];
168
+ answeredCount: number;
169
+ /** 已验证当前版本且尚无回复的条数;历史版与无法重验的未答问题都不计入。 */
170
+ pendingCount: number;
171
+ historyCount: number;
172
+ /** 当前交付目录无法重验该条目版本、因此不声称任何版本关系的条数。 */
173
+ unverifiableCount: number;
174
+ note: string;
175
+ }
176
+ /**
177
+ * Owner 只读的已确认改动详情。
178
+ *
179
+ * 这是「主管确认的改动证据」的可读视图:只经有效 Owner 窗口、精确
180
+ * task/evidence/entry id 与 scope 返回,**查看不写入任何事实**,也不自动知悉。
181
+ */
182
+ export interface OwnerDeliveryChangeView {
183
+ kind: 'SUPERVISOR_CONFIRMED_BOUNDED_WINDOW';
184
+ label: string;
185
+ evidenceId: string;
186
+ entryId: string;
187
+ taskId: string;
188
+ taskTitle: string;
189
+ attemptNo: number;
190
+ status: string;
191
+ repoPath: string;
192
+ revision: string;
193
+ repoVcs: string;
194
+ repoHead: string | null;
195
+ coverageComplete: boolean;
196
+ coverageReasons: string[];
197
+ labels: string[];
198
+ note: string;
199
+ hunks: {
200
+ kind: string;
201
+ beforeLine: number | null;
202
+ afterLine: number | null;
203
+ text: string;
204
+ }[];
205
+ }
63
206
  export interface OwnerDecisionControllerOptions {
64
207
  now?: () => number;
65
208
  validationTimeoutMs?: number;
@@ -83,6 +226,16 @@ export interface OwnerOperationCatalog {
83
226
  }[];
84
227
  runtimeSessions: OwnerRuntimeSessionChoice[];
85
228
  workspaceRoots: string[];
229
+ /**
230
+ * 本次授权范围内的已确认交付条目;逐条知悉与逐条提问共用同一份目录。
231
+ * 只要窗口授权了其中任一动作就返回;读取权限仍由各自动作单独把关。
232
+ */
233
+ deliveryItems?: OwnerDeliveryItemChoice[];
234
+ /**
235
+ * 本次授权范围内**已有提问记录**的精确条目只读入口(含已离开当前目录的旧问答)。
236
+ * 只在窗口授权 `delivery.item.question` 时返回,供只读回看;不是新提问目标来源。
237
+ */
238
+ deliveryQuestionHistory?: OwnerDeliveryQuestionHistoryChoice[];
86
239
  }
87
240
  export type OwnerOperationInput = {
88
241
  action: 'init';
@@ -140,6 +293,27 @@ export type OwnerOperationInput = {
140
293
  } | {
141
294
  action: 'plan.adopt';
142
295
  parameters: PlanAdoptionParameters;
296
+ } | {
297
+ action: 'delivery.item.ack';
298
+ parameters: {
299
+ task_id: string;
300
+ delivery_id: string;
301
+ item_id: string;
302
+ content_hash: string;
303
+ attempt_no: number;
304
+ result_id: string;
305
+ };
306
+ } | {
307
+ action: 'delivery.item.question';
308
+ parameters: {
309
+ task_id: string;
310
+ delivery_id: string;
311
+ item_id: string;
312
+ content_hash: string;
313
+ attempt_no: number;
314
+ result_id: string;
315
+ question_text: string;
316
+ };
143
317
  };
144
318
  export interface OwnerOperationPreview {
145
319
  prepareId: string;
@@ -170,7 +344,7 @@ export interface OwnerOperationReceipt {
170
344
  inputHash: string;
171
345
  status: 'APPLIED';
172
346
  target: {
173
- type: 'kingdom' | 'territory' | 'binding' | 'collaboration-plan';
347
+ type: 'kingdom' | 'territory' | 'binding' | 'collaboration-plan' | 'delivery';
174
348
  id: string;
175
349
  };
176
350
  receiptSeq: number;
@@ -196,6 +370,65 @@ export declare class OwnerDecisionController {
196
370
  };
197
371
  inspect(handle: OwnerDecisionHandle): OwnerDecisionView | null;
198
372
  catalog(handle: OwnerDecisionHandle): Promise<OwnerOperationCatalog>;
373
+ /**
374
+ * 本次授权范围内的**已有提问记录**条目(只读历史入口)。
375
+ *
376
+ * 只读且不依赖有界交付目录:它按权威提问事实列出精确 task/item,再逐条用
377
+ * `deliveryScopeAllows` 过滤,因此不含跨领地条目;不在当前目录、当前无法重验的
378
+ * 旧问答也能在这里被发现。它不返回任何正文,也**不**进入新提问 prepare 的来源目录。
379
+ */
380
+ private deliveryQuestionHistory;
381
+ /**
382
+ * 交付知悉的授权范围判据。
383
+ *
384
+ * catalog 与 prepare/commit 必须共用同一判据:否则会出现「清单可见、
385
+ * 提交被拒」或「清单不可见、提交却可行」。`kingdomWide` 是 Owner 的最高
386
+ * 授权级别;其余情况要求任务所在领地在 `territoryIds` 内,或该领地由
387
+ * 授权 `bindingIds` 中的主管主理且本次授权声明了 SUPERVISOR 角色。
388
+ */
389
+ private deliveryScopeAllows;
390
+ /**
391
+ * 本次授权范围内的已确认交付条目。只有同一 Task/attempt 主管 ACCEPT 的交付才出现,
392
+ * Worker Claim 永远不会进入该清单。
393
+ */
394
+ private deliveryItems;
395
+ /**
396
+ * 只读返回一条已确认交付条目的完整问答线程。
397
+ *
398
+ * 有效性要求与 `readDeliveryChange` 同款:窗口 ACTIVE、本次授权包含
399
+ * `delivery.item.question`、任务在授权范围内、该 task 确实存在写给它的问题记录。
400
+ * 版本关系按该精确 task/item **独立重验**(不受有界展示目录截断影响):命中当前
401
+ * 派生版本即已验证当前版,命中的是旧版本即历史版;条目已无法从当前 ACCEPT/证据
402
+ * 重验(例如 CHANGE 证据丢失)时仍可按精确 itemId 读回,但整条标为无法重验,
403
+ * 不冒充当前版、也不可回复。任一不成立都失败,且不写任何事实、不自动知悉。
404
+ */
405
+ readDeliveryQuestions(handle: OwnerDecisionHandle, input: {
406
+ taskId: string;
407
+ itemId: string;
408
+ }): OwnerDeliveryQuestionView;
409
+ /**
410
+ * 已由主管在 ACCEPT 中显式选择、且本地 hash 重验通过的改动证据。
411
+ * 缺失、漂移或未确认时返回 null:调用方显示「不可定位」,不退回执行者自述。
412
+ */
413
+ private changeEvidenceFor;
414
+ private acceptedChangeRef;
415
+ /**
416
+ * 只读返回一条已确认改动条目的有界详情。
417
+ *
418
+ * 有效性要求:窗口 ACTIVE、**本次授权动作包含 `delivery.item.ack`**、任务在本次
419
+ * 授权范围内、该 task 确实存在一条主管 ACCEPT 绑定的改动证据、evidence id 与
420
+ * entry id 精确匹配、该条目仍需出现在当前有效交付目录中,且本地 hash 重验通过。
421
+ * 任一不成立都失败,且不写任何事实、不产生知悉。
422
+ *
423
+ * 只检查 ACTIVE + Territory scope 是不够的:同一领地的另一个管理窗口若没有该
424
+ * 动作授权,就不能凭 id 读取差异正文。这里与 `catalog` 使用同一动作判据,
425
+ * 不默认放行(也不新增只读动作)。
426
+ */
427
+ readDeliveryChange(handle: OwnerDecisionHandle, input: {
428
+ taskId: string;
429
+ evidenceId: string;
430
+ entryId: string;
431
+ }): OwnerDeliveryChangeView;
199
432
  prepare(handle: OwnerDecisionHandle, raw: OwnerOperationInput, options?: {
200
433
  signal?: AbortSignal;
201
434
  }): Promise<OwnerOperationPreview>;
@@ -106,12 +106,34 @@ export interface StartTaskInput {
106
106
  * - executor 客观失败 → **RUNNING → FAILED** + `WORKER_EXECUTION_FAILED`,且不落 Claim。
107
107
  */
108
108
  export declare function startTask(store: KingdomStore, executor: WorkerExecutor, ctx: CommandContext, input: StartTaskInput): Promise<CommandResultView>;
109
+ /**
110
+ * 主管只读候选清单:列出本 Task 当前 attempt 的有界改动条目。
111
+ *
112
+ * 这是主管「查看候选并显式选择」的入口;它只读、不写任何事实,也要求
113
+ * 真实 session-bound 主管。没有快照时如实说明,不伪造候选。
114
+ */
115
+ export declare function describeTaskChangeCandidates(store: KingdomStore, ctx: CommandContext, taskId: string): {
116
+ ok: true;
117
+ text: string;
118
+ } | {
119
+ ok: false;
120
+ code: KingdomErrorCode;
121
+ message: string;
122
+ };
109
123
  export interface ReviewTaskInput {
110
124
  taskId: string;
111
125
  decision: string;
112
126
  reason?: string;
113
127
  /** HANDOFF 专用:目标 Worker binding id。 */
114
128
  to_binding_id?: string;
129
+ /**
130
+ * ACCEPT 专用:主管显式选择属于本次交付的改动引用。
131
+ *
132
+ * 两者必须同时给出;只给 evidence id 或只给空选择都视为非法,普通 ACCEPT
133
+ * 不会自动确认全部 diff。确认入口额外要求真实 session-bound 主管会话。
134
+ */
135
+ change_evidence_id?: string;
136
+ change_entry_ids?: string[];
115
137
  }
116
138
  /**
117
139
  * Supervisor 审查 Worker Claim,把 Claim 转成组织事实(v0.7.0:scope + HANDOFF + Ledger 关闭)。