@gajae-code/coding-agent 0.18.6 → 0.18.8

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 (302) hide show
  1. package/CHANGELOG.md +318 -1
  2. package/dist/types/async/job-manager.d.ts +1 -1
  3. package/dist/types/capability/mcp.d.ts +2 -0
  4. package/dist/types/capability/skill.d.ts +2 -0
  5. package/dist/types/capability/types.d.ts +6 -0
  6. package/dist/types/cli/public-command-errors.d.ts +3 -1
  7. package/dist/types/cli/setup-cli.d.ts +1 -1
  8. package/dist/types/commands/deep-interview.d.ts +3 -0
  9. package/dist/types/config/autorouting-tier-map.d.ts +348 -9
  10. package/dist/types/config/file-lock.d.ts +1 -0
  11. package/dist/types/config/model-bindings-applier.d.ts +2 -0
  12. package/dist/types/config/model-profile-activation.d.ts +11 -3
  13. package/dist/types/config/model-registry.d.ts +4 -9
  14. package/dist/types/config/settings.d.ts +4 -0
  15. package/dist/types/config/skill-settings-defaults.d.ts +2 -0
  16. package/dist/types/cursor-delete-path.d.ts +1 -0
  17. package/dist/types/cursor-mcp-name.d.ts +8 -0
  18. package/dist/types/customization/inventory.d.ts +2 -0
  19. package/dist/types/debug/report-bundle-parent.d.ts +2 -0
  20. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.d.ts +1 -0
  21. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.d.ts +31 -0
  22. package/dist/types/defaults/gjc-skills.generated.d.ts +5 -6
  23. package/dist/types/discovery/helpers.d.ts +8 -3
  24. package/dist/types/export/html/css-color.d.ts +2 -0
  25. package/dist/types/export/html/template.generated.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/types.d.ts +7 -0
  27. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +14 -1
  28. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +2 -0
  29. package/dist/types/extensibility/plugins/plugin-link-path.d.ts +2 -0
  30. package/dist/types/extensibility/runtime-skill-discovery.d.ts +3 -1
  31. package/dist/types/extensibility/skill-management.d.ts +3 -1
  32. package/dist/types/extensibility/skills.d.ts +2 -0
  33. package/dist/types/gjc-runtime/deep-interview-crystallize.d.ts +74 -0
  34. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +11 -0
  35. package/dist/types/gjc-runtime/gc-runtime.d.ts +5 -0
  36. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +0 -5
  37. package/dist/types/gjc-runtime/state-argv.d.ts +1 -1
  38. package/dist/types/gjc-runtime/state-migrations.d.ts +8 -0
  39. package/dist/types/gjc-runtime/state-runtime.d.ts +95 -0
  40. package/dist/types/gjc-runtime/state-writer.d.ts +11 -1
  41. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -0
  42. package/dist/types/internal-urls/skill-path.d.ts +1 -0
  43. package/dist/types/lsp/workspace-path.d.ts +1 -0
  44. package/dist/types/modes/acp/acp-agent.d.ts +7 -0
  45. package/dist/types/modes/components/custom-editor.d.ts +6 -0
  46. package/dist/types/modes/components/customization/customization-dashboard.d.ts +1 -0
  47. package/dist/types/modes/components/extensions/state-manager.d.ts +4 -3
  48. package/dist/types/modes/controllers/input-controller.d.ts +9 -0
  49. package/dist/types/modes/interactive-mode.d.ts +1 -0
  50. package/dist/types/modes/utils/interrupt-ownership.d.ts +3 -0
  51. package/dist/types/modes/utils/keybinding-matchers.d.ts +1 -0
  52. package/dist/types/modes/utils/macos-option-forwarding.d.ts +17 -0
  53. package/dist/types/progress/collect-project-progress.d.ts +38 -0
  54. package/dist/types/progress/progress-contract.d.ts +154 -0
  55. package/dist/types/progress/progress-snapshot.d.ts +11 -0
  56. package/dist/types/progress/project-progress.d.ts +141 -0
  57. package/dist/types/progress/render-progress.d.ts +28 -0
  58. package/dist/types/runtime-mcp/elicitation.d.ts +12 -0
  59. package/dist/types/runtime-mcp/oauth-public-url.d.ts +1 -0
  60. package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +1 -0
  61. package/dist/types/runtime-mcp/smithery-registry.d.ts +24 -0
  62. package/dist/types/runtime-mcp/types.d.ts +6 -0
  63. package/dist/types/sdk/acp/adapter.d.ts +1 -1
  64. package/dist/types/sdk/broker/broker-exit.d.ts +6 -2
  65. package/dist/types/sdk/broker/broker.d.ts +18 -1
  66. package/dist/types/sdk/broker/lifecycle.d.ts +9 -0
  67. package/dist/types/sdk/broker/session-index.d.ts +12 -6
  68. package/dist/types/sdk/broker/task-artifact-owner-validation.d.ts +55 -0
  69. package/dist/types/sdk/bus/index.d.ts +12 -1
  70. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -1
  71. package/dist/types/sdk/bus/telegram-daemon.d.ts +3 -2
  72. package/dist/types/sdk/client/client.d.ts +2 -0
  73. package/dist/types/sdk/host/host.d.ts +6 -0
  74. package/dist/types/sdk/host/query/handlers.d.ts +3 -0
  75. package/dist/types/sdk/index.d.ts +1 -0
  76. package/dist/types/sdk/router/session-router.d.ts +9 -0
  77. package/dist/types/sdk/session-list.d.ts +1 -1
  78. package/dist/types/sdk/session.d.ts +8 -0
  79. package/dist/types/session/agent-session.d.ts +38 -9
  80. package/dist/types/session/artifacts.d.ts +2 -2
  81. package/dist/types/session/internal/managed-gc-retirement-codec.d.ts +32 -0
  82. package/dist/types/session/internal/managed-session-scope.d.ts +79 -2
  83. package/dist/types/session/internal/managed-session-storage.d.ts +36 -1
  84. package/dist/types/session/internal/managed-task-owner-cleanup.d.ts +62 -0
  85. package/dist/types/session/internal/task-artifact-owner-access.d.ts +19 -0
  86. package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +11 -0
  87. package/dist/types/session/session-manager.d.ts +31 -5
  88. package/dist/types/session/session-retirement.d.ts +71 -0
  89. package/dist/types/session/session-storage.d.ts +62 -48
  90. package/dist/types/session/session-transcript-header.d.ts +2 -0
  91. package/dist/types/session/task-artifact-owner-codec.d.ts +109 -0
  92. package/dist/types/session/task-artifact-owner-retirement.d.ts +7 -0
  93. package/dist/types/session/task-artifact-owner.d.ts +10 -0
  94. package/dist/types/setup/credential-auto-import.d.ts +1 -1
  95. package/dist/types/setup/credential-import.d.ts +6 -4
  96. package/dist/types/skill-state/active-state.d.ts +38 -0
  97. package/dist/types/slash-commands/helpers/progress-report.d.ts +8 -0
  98. package/dist/types/task/executor.d.ts +3 -0
  99. package/dist/types/tools/bash-skill-urls.d.ts +1 -1
  100. package/dist/types/tools/index.d.ts +3 -0
  101. package/dist/types/tools/python.d.ts +9 -1
  102. package/dist/types/tools/recipe/recipe-guard.d.ts +7 -0
  103. package/dist/types/tools/restricted-cwd.d.ts +1 -0
  104. package/dist/types/tools/todo-write.d.ts +6 -0
  105. package/dist/types/utils/tools-checksum.d.ts +7 -0
  106. package/package.json +7 -7
  107. package/scripts/generate-sdk-operation-inventory.ts +21 -0
  108. package/scripts/resident-memory-bench.ts +174 -20
  109. package/scripts/verify-managed-empty-stop.ts +28 -0
  110. package/src/async/job-manager.ts +228 -122
  111. package/src/capability/index.ts +18 -0
  112. package/src/capability/mcp.ts +2 -0
  113. package/src/capability/skill.ts +2 -0
  114. package/src/capability/types.ts +6 -0
  115. package/src/cli/auth-broker-cli.ts +1 -1
  116. package/src/cli/config-cli.ts +8 -18
  117. package/src/cli/customize-doctor.ts +15 -2
  118. package/src/cli/public-command-errors.ts +21 -1
  119. package/src/cli/setup-cli.ts +4 -4
  120. package/src/cli/skills-cli.ts +5 -0
  121. package/src/cli-main.ts +7 -8
  122. package/src/commands/deep-interview.ts +47 -8
  123. package/src/commands/sdk.ts +140 -29
  124. package/src/config/autorouting-tier-map.ts +117 -7
  125. package/src/config/file-lock.ts +307 -68
  126. package/src/config/mcp-schema.json +4 -0
  127. package/src/config/model-bindings-applier.ts +20 -0
  128. package/src/config/model-profile-activation.ts +240 -46
  129. package/src/config/model-registry.ts +47 -153
  130. package/src/config/settings.ts +44 -4
  131. package/src/config/skill-settings-defaults.ts +7 -0
  132. package/src/coordinator-mcp/policy.ts +3 -2
  133. package/src/cursor-delete-path.ts +10 -0
  134. package/src/cursor-mcp-name.ts +15 -0
  135. package/src/cursor.ts +13 -2
  136. package/src/customization/inventory.ts +3 -0
  137. package/src/debug/report-bundle-parent.ts +22 -0
  138. package/src/debug/report-bundle.ts +3 -0
  139. package/src/debug/system-info.ts +13 -1
  140. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.ts +67 -4
  141. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.ts +80 -0
  142. package/src/defaults/gjc/skills/deep-interview/SKILL.md +105 -10
  143. package/src/defaults/gjc/skills/ralplan/SKILL.md +6 -4
  144. package/src/defaults/gjc-defaults.test.ts +18 -1
  145. package/src/defaults/gjc-defaults.ts +3 -0
  146. package/src/defaults/gjc-skills.generated.ts +58 -36
  147. package/src/discovery/agents.ts +6 -1
  148. package/src/discovery/builtin.ts +10 -0
  149. package/src/discovery/helpers.ts +168 -23
  150. package/src/discovery/mcp-json.ts +6 -0
  151. package/src/discovery/ssh.ts +9 -4
  152. package/src/discovery/substitute-plugin-root.ts +3 -1
  153. package/src/edit/file-read-cache.ts +1 -1
  154. package/src/eval/py/executor.ts +380 -120
  155. package/src/export/html/css-color.ts +9 -0
  156. package/src/export/html/index.ts +5 -4
  157. package/src/export/html/template.generated.ts +1 -1
  158. package/src/extensibility/extensions/runner.ts +4 -0
  159. package/src/extensibility/extensions/types.ts +7 -0
  160. package/src/extensibility/gjc-plugins/runtime-adapters.ts +73 -8
  161. package/src/extensibility/plugins/manager.ts +3 -2
  162. package/src/extensibility/plugins/marketplace/cache.ts +15 -0
  163. package/src/extensibility/plugins/marketplace/manager.ts +11 -3
  164. package/src/extensibility/plugins/plugin-link-path.ts +12 -0
  165. package/src/extensibility/runtime-skill-discovery.ts +20 -2
  166. package/src/extensibility/skill-management.ts +6 -2
  167. package/src/extensibility/skills.ts +6 -1
  168. package/src/gjc-runtime/deep-interview-crystallize.ts +1814 -0
  169. package/src/gjc-runtime/deep-interview-recorder.ts +20 -2
  170. package/src/gjc-runtime/deep-interview-runtime.ts +1415 -13
  171. package/src/gjc-runtime/deep-interview-stage.ts +98 -21
  172. package/src/gjc-runtime/gc-runtime.ts +206 -8
  173. package/src/gjc-runtime/launch-worktree.ts +14 -4
  174. package/src/gjc-runtime/ralplan-runtime.ts +447 -52
  175. package/src/gjc-runtime/state-argv.ts +2 -0
  176. package/src/gjc-runtime/state-migrations.ts +91 -29
  177. package/src/gjc-runtime/state-runtime.ts +3716 -135
  178. package/src/gjc-runtime/state-writer.ts +83 -8
  179. package/src/gjc-runtime/ultragoal-runtime.ts +16 -4
  180. package/src/gjc-runtime/workflow-manifest.generated.json +70 -42
  181. package/src/gjc-runtime/workflow-manifest.ts +54 -21
  182. package/src/harness-control-plane/operate.ts +12 -4
  183. package/src/harness-control-plane/owner.ts +5 -1
  184. package/src/hashline/parser.ts +48 -9
  185. package/src/hashline/recovery.ts +13 -4
  186. package/src/hindsight/config.ts +9 -3
  187. package/src/internal-urls/docs-index.generated.ts +19 -18
  188. package/src/internal-urls/skill-path.ts +19 -0
  189. package/src/internal-urls/skill-protocol.ts +2 -0
  190. package/src/lsp/edits.ts +6 -0
  191. package/src/lsp/workspace-path.ts +51 -0
  192. package/src/main.ts +195 -31
  193. package/src/modes/acp/acp-agent.ts +163 -7
  194. package/src/modes/components/custom-editor.ts +14 -0
  195. package/src/modes/components/customization/customization-dashboard.ts +12 -0
  196. package/src/modes/components/extensions/extension-dashboard.ts +2 -2
  197. package/src/modes/components/extensions/state-manager.ts +15 -5
  198. package/src/modes/components/model-selector.ts +1 -4
  199. package/src/modes/components/provider-onboarding-selector.ts +1 -1
  200. package/src/modes/components/status-line/segments.ts +4 -0
  201. package/src/modes/controllers/event-controller.ts +11 -4
  202. package/src/modes/controllers/input-controller.ts +74 -29
  203. package/src/modes/controllers/runtime-mcp-command-controller.ts +8 -3
  204. package/src/modes/controllers/selector-controller.ts +28 -15
  205. package/src/modes/interactive-mode.ts +4 -0
  206. package/src/modes/runtime-init.ts +4 -0
  207. package/src/modes/utils/abort-message.ts +3 -1
  208. package/src/modes/utils/interrupt-ownership.ts +12 -0
  209. package/src/modes/utils/keybinding-matchers.ts +4 -0
  210. package/src/modes/utils/macos-option-forwarding.ts +80 -0
  211. package/src/progress/collect-project-progress.ts +153 -0
  212. package/src/progress/progress-contract.ts +172 -0
  213. package/src/progress/progress-snapshot.ts +140 -0
  214. package/src/progress/project-progress.ts +446 -0
  215. package/src/progress/render-progress.ts +209 -0
  216. package/src/prompts/system/master-mode.md +1 -0
  217. package/src/prompts/tools/skill-discovery.md +1 -1
  218. package/src/runtime-mcp/client.ts +13 -4
  219. package/src/runtime-mcp/config-writer.ts +10 -6
  220. package/src/runtime-mcp/config.ts +1 -0
  221. package/src/runtime-mcp/elicitation.ts +142 -0
  222. package/src/runtime-mcp/oauth-flow.ts +5 -0
  223. package/src/runtime-mcp/oauth-public-url.ts +8 -0
  224. package/src/runtime-mcp/plugin-network-boundary.ts +4 -0
  225. package/src/runtime-mcp/smithery-registry.ts +22 -3
  226. package/src/runtime-mcp/transports/http.ts +2 -2
  227. package/src/runtime-mcp/types.ts +6 -0
  228. package/src/sdk/acp/adapter.ts +93 -8
  229. package/src/sdk/broker/broker-exit.ts +52 -23
  230. package/src/sdk/broker/broker.ts +83 -7
  231. package/src/sdk/broker/ensure.ts +2 -0
  232. package/src/sdk/broker/lifecycle.ts +820 -73
  233. package/src/sdk/broker/session-index.ts +191 -81
  234. package/src/sdk/broker/task-artifact-owner-validation.ts +259 -0
  235. package/src/sdk/bus/chat-daemon-cli.ts +38 -1
  236. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  237. package/src/sdk/bus/chat-daemon-runtime.ts +3 -0
  238. package/src/sdk/bus/index.ts +241 -46
  239. package/src/sdk/bus/telegram-daemon-contract.ts +6 -1
  240. package/src/sdk/bus/telegram-daemon.ts +4 -2
  241. package/src/sdk/cli/session-cli.ts +17 -3
  242. package/src/sdk/client/client.ts +28 -8
  243. package/src/sdk/host/host.ts +6 -0
  244. package/src/sdk/host/query/handlers.ts +9 -1
  245. package/src/sdk/host/session-runtime.test.ts +2805 -411
  246. package/src/sdk/host/session-runtime.ts +428 -111
  247. package/src/sdk/host/surface-policy.ts +1 -0
  248. package/src/sdk/index.ts +8 -0
  249. package/src/sdk/lifecycle-session.ts +3 -1
  250. package/src/sdk/mcp/server.ts +15 -3
  251. package/src/sdk/prompt-deadline-manager.ts +15 -0
  252. package/src/sdk/protocol/operation-inventory.generated.json +146 -0
  253. package/src/sdk/protocol/operation-registry.ts +9 -2
  254. package/src/sdk/router/session-router.ts +94 -14
  255. package/src/sdk/session-list.ts +1 -0
  256. package/src/sdk/session.ts +81 -38
  257. package/src/session/agent-session.ts +674 -224
  258. package/src/session/artifacts.ts +174 -70
  259. package/src/session/internal/managed-gc-retirement-codec.ts +319 -0
  260. package/src/session/internal/managed-session-scope.ts +3457 -462
  261. package/src/session/internal/managed-session-storage.ts +482 -61
  262. package/src/session/internal/managed-task-owner-cleanup.ts +473 -0
  263. package/src/session/internal/task-artifact-owner-access.ts +245 -0
  264. package/src/session/internal/task-artifact-owner-transcript.ts +614 -0
  265. package/src/session/session-manager.ts +939 -133
  266. package/src/session/session-retirement.ts +714 -0
  267. package/src/session/session-storage.ts +418 -174
  268. package/src/session/session-transcript-header.ts +17 -0
  269. package/src/session/task-artifact-owner-codec.ts +641 -0
  270. package/src/session/task-artifact-owner-retirement.ts +477 -0
  271. package/src/session/task-artifact-owner.ts +289 -0
  272. package/src/setup/credential-auto-import.ts +12 -3
  273. package/src/setup/credential-import.ts +176 -5
  274. package/src/setup/paseo/announce.ts +6 -1
  275. package/src/skill-state/active-state.ts +132 -2
  276. package/src/slash-commands/builtin-registry.ts +39 -9
  277. package/src/slash-commands/helpers/progress-report.ts +23 -0
  278. package/src/stt/setup.ts +3 -5
  279. package/src/task/commands.ts +3 -1
  280. package/src/task/executor.ts +4 -0
  281. package/src/task/index.ts +6 -0
  282. package/src/tools/ask.ts +205 -6
  283. package/src/tools/ast-edit.ts +4 -0
  284. package/src/tools/bash-allowed-prefixes.ts +15 -0
  285. package/src/tools/bash-skill-urls.ts +56 -3
  286. package/src/tools/bash.ts +48 -79
  287. package/src/tools/descriptors.ts +5 -1
  288. package/src/tools/eval.ts +56 -36
  289. package/src/tools/image-gen.ts +1 -1
  290. package/src/tools/index.ts +3 -0
  291. package/src/tools/python.ts +187 -66
  292. package/src/tools/recipe/index.ts +9 -0
  293. package/src/tools/recipe/recipe-guard.ts +19 -0
  294. package/src/tools/restricted-cwd.ts +10 -0
  295. package/src/tools/skill-discovery.ts +5 -0
  296. package/src/tools/skill.ts +28 -1
  297. package/src/tools/todo-write.ts +10 -1
  298. package/src/tools/tool-catalog.generated.ts +1 -1
  299. package/src/tools/write.ts +1 -0
  300. package/src/utils/tools-checksum.ts +34 -0
  301. package/src/utils/tools-manager.ts +24 -6
  302. package/src/web/search/providers/codex.ts +3 -2
@@ -0,0 +1,473 @@
1
+ import * as path from "node:path";
2
+ import * as util from "node:util";
3
+ import type { ResumeSessionIdentity } from "../session-manager";
4
+ import {
5
+ FileSessionStorage,
6
+ type SessionStorageSnapshot,
7
+ type VerifiedSessionDeleteResult,
8
+ type VerifiedSessionDeleteTarget,
9
+ } from "../session-storage";
10
+ import type { TaskArtifactOwnerDeletionEvidence, TaskArtifactOwnerStorageContext } from "../task-artifact-owner-codec";
11
+ import {
12
+ parseTaskArtifactOwnerDeletionEvidence,
13
+ parseTaskArtifactOwnerRetirementOutcome,
14
+ } from "../task-artifact-owner-codec";
15
+ import { retireTaskArtifactOwner, verifyTaskArtifactOwnerPhysicalRetirement } from "../task-artifact-owner-retirement";
16
+ import type {
17
+ ManagedGcSessionRetirementReceipt,
18
+ ManagedGcSessionRetirementTarget,
19
+ } from "./managed-gc-retirement-codec";
20
+ import type { ManagedGcProtocolScopeInspector } from "./managed-session-scope";
21
+ import { captureTaskArtifactOwnerDeletionEvidence } from "./task-artifact-owner-access";
22
+ import {
23
+ hasSiblingTaskArtifactOwnerTranscript,
24
+ taskArtifactOwnerLocatorFromTranscriptBytes,
25
+ } from "./task-artifact-owner-transcript";
26
+
27
+ export interface ManagedGcOwnerCleanupTarget {
28
+ readonly path: string;
29
+ readonly sessionId: string;
30
+ readonly cwd: string;
31
+ readonly identity: ResumeSessionIdentity;
32
+ readonly taskArtifactOwnerDeletionEvidence?: TaskArtifactOwnerDeletionEvidence;
33
+ }
34
+
35
+ /** Authenticated receipt operations and fencing supplied by the prepared managed scope. */
36
+ export interface ManagedGcOwnerCleanupAuthority {
37
+ readonly agentDir: string;
38
+ readonly sessionsRoot: string;
39
+ readonly directoryPath: string;
40
+ readonly storageContext: TaskArtifactOwnerStorageContext;
41
+ readonly inspectProtocol: ManagedGcProtocolScopeInspector;
42
+ readonly assertOwned: () => void;
43
+ readonly bindTarget: (transcriptPath: string) => ManagedGcSessionRetirementTarget;
44
+ readonly readReceipt: (transcriptPath: string) => Promise<ManagedGcSessionRetirementReceipt | undefined>;
45
+ readonly publishReceipt: (receipt: ManagedGcSessionRetirementReceipt) => Promise<ManagedGcSessionRetirementReceipt>;
46
+ readonly findCompletedRetirement: (
47
+ evidence: TaskArtifactOwnerDeletionEvidence,
48
+ exceptTranscriptPath: string,
49
+ ) => Promise<
50
+ | {
51
+ scope: { readonly agentDir: string; readonly sessionsRoot: string; readonly directoryPath: string };
52
+ receipt: ManagedGcSessionRetirementReceipt;
53
+ }
54
+ | undefined
55
+ >;
56
+ }
57
+
58
+ export type ManagedGcOwnerProgress = {
59
+ readonly state: "none" | "owner_retired" | "payload_retired" | "pending";
60
+ readonly message?: string;
61
+ };
62
+
63
+ export type ManagedGcOwnerDeleteFields = Pick<
64
+ VerifiedSessionDeleteTarget,
65
+ | "taskArtifactOwnerStorageContext"
66
+ | "taskArtifactOwnerDeletionEvidence"
67
+ | "taskArtifactOwnerRetirementOutcome"
68
+ | "taskArtifactOwnerRetirementContinuation"
69
+ | "taskArtifactOwnerPayloadRetired"
70
+ | "taskArtifactOwnerNamespaceRetained"
71
+ | "deferTaskArtifactOwnerRetirement"
72
+ | "taskArtifactOwnerRetired"
73
+ >;
74
+
75
+ function deepSame(left: unknown, right: unknown): boolean {
76
+ return util.isDeepStrictEqual(left, right);
77
+ }
78
+
79
+ function managedGcTargetMatchesCandidate(
80
+ target: ManagedGcSessionRetirementTarget,
81
+ candidate: ManagedGcOwnerCleanupTarget,
82
+ ): boolean {
83
+ return (
84
+ target.transcriptPath === candidate.path &&
85
+ target.sessionId === candidate.sessionId &&
86
+ target.cwd === candidate.cwd &&
87
+ target.transcriptIdentity.nlink === 1n &&
88
+ target.transcriptIdentity.dev === candidate.identity.dev &&
89
+ target.transcriptIdentity.ino === candidate.identity.ino &&
90
+ target.transcriptIdentity.size === candidate.identity.size &&
91
+ target.transcriptIdentity.mtimeNs === candidate.identity.mtimeNs &&
92
+ target.transcriptIdentity.sha256 === candidate.identity.sha256
93
+ );
94
+ }
95
+
96
+ function managedGcReceiptTarget(receipt: ManagedGcSessionRetirementReceipt): ManagedGcSessionRetirementTarget {
97
+ return {
98
+ transcriptPath: receipt.transcriptPath,
99
+ sessionId: receipt.sessionId,
100
+ cwd: receipt.cwd,
101
+ transcriptIdentity: receipt.transcriptIdentity,
102
+ taskArtifactOwnerLocator: receipt.taskArtifactOwnerDeletionEvidence.locator,
103
+ };
104
+ }
105
+
106
+ export function hasUnsupportedLegacyOwnerTarget(scopeDirectory: string, target: ManagedGcOwnerCleanupTarget): boolean {
107
+ if (path.dirname(target.path) === scopeDirectory) return false;
108
+ if (target.taskArtifactOwnerDeletionEvidence) return true;
109
+ let snapshot: SessionStorageSnapshot;
110
+ try {
111
+ snapshot = new FileSessionStorage().readSnapshotSync(target.path);
112
+ } catch (error) {
113
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
114
+ throw error;
115
+ }
116
+ return taskArtifactOwnerLocatorFromTranscriptBytes(snapshot.bytes, target.sessionId) !== undefined;
117
+ }
118
+
119
+ export async function prepareManagedGcOwnerTarget<T extends ManagedGcOwnerCleanupTarget>(
120
+ authority: ManagedGcOwnerCleanupAuthority,
121
+ target: T,
122
+ ): Promise<T & ManagedGcOwnerCleanupTarget> {
123
+ if (path.dirname(target.path) !== authority.directoryPath) {
124
+ if (hasUnsupportedLegacyOwnerTarget(authority.directoryPath, target))
125
+ throw new Error("task_artifact_owner_legacy_scope_unsupported");
126
+ return target;
127
+ }
128
+ const receipt = await authority.readReceipt(target.path);
129
+ if (receipt) {
130
+ if (
131
+ !managedGcTargetMatchesCandidate(receipt, target) ||
132
+ (target.taskArtifactOwnerDeletionEvidence &&
133
+ !deepSame(target.taskArtifactOwnerDeletionEvidence, receipt.taskArtifactOwnerDeletionEvidence))
134
+ )
135
+ throw new Error("task_artifact_owner_continuation_evidence_mismatch");
136
+ return { ...target, taskArtifactOwnerDeletionEvidence: receipt.taskArtifactOwnerDeletionEvidence };
137
+ }
138
+ if (target.taskArtifactOwnerDeletionEvidence) throw new Error("task_artifact_owner_continuation_state_missing");
139
+ let snapshot: SessionStorageSnapshot;
140
+ try {
141
+ snapshot = new FileSessionStorage().readSnapshotSync(target.path);
142
+ } catch (error) {
143
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return target;
144
+ throw error;
145
+ }
146
+ const locator = taskArtifactOwnerLocatorFromTranscriptBytes(snapshot.bytes, target.sessionId);
147
+ if (!locator) return target;
148
+ const bound = authority.bindTarget(target.path);
149
+ if (!managedGcTargetMatchesCandidate(bound, target) || !deepSame(locator, bound.taskArtifactOwnerLocator))
150
+ throw new Error("task_artifact_owner_continuation_transcript_replaced");
151
+ const evidence = captureTaskArtifactOwnerDeletionEvidence(authority.storageContext, target.sessionId, locator);
152
+ if (!evidence) throw new Error("task_artifact_owner_deletion_evidence_missing");
153
+ const prepared = await authority.publishReceipt({
154
+ ...bound,
155
+ state: "prepared",
156
+ taskArtifactOwnerDeletionEvidence: evidence,
157
+ });
158
+ if (
159
+ !deepSame(prepared.taskArtifactOwnerDeletionEvidence, evidence) ||
160
+ !managedGcTargetMatchesCandidate(prepared, target)
161
+ )
162
+ throw new Error("task_artifact_owner_continuation_evidence_mismatch");
163
+ return { ...target, taskArtifactOwnerDeletionEvidence: evidence };
164
+ }
165
+
166
+ export async function prepareManagedGcOwnerTargets<T extends ManagedGcOwnerCleanupTarget>(
167
+ authority: ManagedGcOwnerCleanupAuthority,
168
+ targets: readonly T[],
169
+ ): Promise<(T & ManagedGcOwnerCleanupTarget)[]> {
170
+ const prepared: (T & ManagedGcOwnerCleanupTarget)[] = [];
171
+ for (const target of targets) prepared.push(await prepareManagedGcOwnerTarget(authority, target));
172
+ return prepared;
173
+ }
174
+
175
+ export async function managedGcOwnerDeleteFields(
176
+ authority: ManagedGcOwnerCleanupAuthority,
177
+ target: ManagedGcOwnerCleanupTarget,
178
+ ): Promise<ManagedGcOwnerDeleteFields> {
179
+ if (path.dirname(target.path) !== authority.directoryPath) {
180
+ if (hasUnsupportedLegacyOwnerTarget(authority.directoryPath, target))
181
+ throw new Error("task_artifact_owner_legacy_scope_unsupported");
182
+ return {};
183
+ }
184
+ const receipt = await authority.readReceipt(target.path);
185
+ if (!receipt) {
186
+ if (target.taskArtifactOwnerDeletionEvidence) throw new Error("task_artifact_owner_continuation_state_missing");
187
+ return {};
188
+ }
189
+ if (
190
+ !managedGcTargetMatchesCandidate(receipt, target) ||
191
+ !deepSame(receipt.taskArtifactOwnerDeletionEvidence, target.taskArtifactOwnerDeletionEvidence)
192
+ )
193
+ throw new Error("task_artifact_owner_continuation_evidence_mismatch");
194
+ const outcome = receipt.taskArtifactOwnerRetirementOutcome;
195
+ return {
196
+ taskArtifactOwnerStorageContext: authority.storageContext,
197
+ taskArtifactOwnerDeletionEvidence: receipt.taskArtifactOwnerDeletionEvidence,
198
+ deferTaskArtifactOwnerRetirement: true,
199
+ ...(outcome ? { taskArtifactOwnerRetirementOutcome: outcome } : {}),
200
+ ...(outcome && outcome.kind !== "completed"
201
+ ? { taskArtifactOwnerRetirementContinuation: outcome.continuation }
202
+ : {}),
203
+ ...(outcome?.kind === "payload_retired"
204
+ ? { taskArtifactOwnerPayloadRetired: true as const, taskArtifactOwnerNamespaceRetained: true as const }
205
+ : {}),
206
+ ...(receipt.state === "owner_retired" ? { taskArtifactOwnerRetired: true as const } : {}),
207
+ };
208
+ }
209
+
210
+ export async function publishManagedGcArtifactsRemoved(
211
+ authority: ManagedGcOwnerCleanupAuthority,
212
+ target: ManagedGcOwnerCleanupTarget,
213
+ ): Promise<ManagedGcSessionRetirementReceipt | undefined> {
214
+ if (!target.taskArtifactOwnerDeletionEvidence) return undefined;
215
+ const receipt = await authority.readReceipt(target.path);
216
+ if (!receipt) throw new Error("task_artifact_owner_continuation_state_missing");
217
+ if (!deepSame(receipt.taskArtifactOwnerDeletionEvidence, target.taskArtifactOwnerDeletionEvidence))
218
+ throw new Error("task_artifact_owner_continuation_evidence_mismatch");
219
+ if (receipt.state !== "prepared") return receipt;
220
+ return authority.publishReceipt({
221
+ ...managedGcReceiptTarget(receipt),
222
+ state: "artifacts_removed",
223
+ taskArtifactOwnerDeletionEvidence: receipt.taskArtifactOwnerDeletionEvidence,
224
+ artifactsRemoved: true,
225
+ });
226
+ }
227
+
228
+ export async function retireManagedGcOwnerAfterArtifacts(
229
+ authority: ManagedGcOwnerCleanupAuthority,
230
+ target: ManagedGcOwnerCleanupTarget,
231
+ tombstoneTargets: readonly ManagedGcOwnerCleanupTarget[],
232
+ ): Promise<ManagedGcOwnerProgress> {
233
+ if (!target.taskArtifactOwnerDeletionEvidence) return { state: "none" };
234
+ const receipt = await publishManagedGcArtifactsRemoved(authority, target);
235
+ if (!receipt) return { state: "none" };
236
+ const evidence = receipt.taskArtifactOwnerDeletionEvidence;
237
+ if (!evidence) throw new Error("task_artifact_owner_continuation_evidence_missing");
238
+ authority.assertOwned();
239
+ const sharedBefore = await hasSiblingTaskArtifactOwnerTranscript(
240
+ new FileSessionStorage(),
241
+ target.path,
242
+ evidence.locator,
243
+ authority.storageContext,
244
+ authority.inspectProtocol,
245
+ );
246
+ authority.assertOwned();
247
+ if (sharedBefore) return { state: "pending", message: "task_artifact_owner_shared_with_sibling_transcript" };
248
+ if (receipt.state === "owner_retired") return { state: "owner_retired" };
249
+ for (const sibling of tombstoneTargets) {
250
+ if (
251
+ sibling.path === target.path ||
252
+ !sibling.taskArtifactOwnerDeletionEvidence ||
253
+ !deepSame(sibling.taskArtifactOwnerDeletionEvidence, evidence)
254
+ )
255
+ continue;
256
+ const siblingReceipt = await authority.readReceipt(sibling.path);
257
+ const siblingOutcome = siblingReceipt?.taskArtifactOwnerRetirementOutcome;
258
+ if (
259
+ siblingReceipt?.state !== "owner_retired" ||
260
+ siblingOutcome?.kind !== "completed" ||
261
+ !deepSame(siblingReceipt.taskArtifactOwnerDeletionEvidence, evidence)
262
+ )
263
+ continue;
264
+ const inherited = await authority.publishReceipt({
265
+ ...managedGcReceiptTarget(receipt),
266
+ state: "owner_retired",
267
+ taskArtifactOwnerDeletionEvidence: evidence,
268
+ artifactsRemoved: true,
269
+ taskArtifactOwnerRetirementOutcome: siblingOutcome,
270
+ taskArtifactOwnerRetired: true,
271
+ });
272
+ if (inherited.state !== "owner_retired") throw new Error("task_artifact_owner_inheritance_pending");
273
+ return { state: "owner_retired" };
274
+ }
275
+ const inherited = await authority.findCompletedRetirement(evidence, target.path);
276
+ if (inherited) {
277
+ if (
278
+ inherited.scope.agentDir !== authority.agentDir ||
279
+ inherited.scope.sessionsRoot !== authority.sessionsRoot ||
280
+ inherited.scope.directoryPath === authority.directoryPath ||
281
+ path.dirname(inherited.receipt.transcriptPath) !== inherited.scope.directoryPath ||
282
+ inherited.receipt.transcriptPath === target.path ||
283
+ inherited.receipt.state !== "owner_retired"
284
+ )
285
+ throw new Error("task_artifact_owner_continuation_authority_mismatch");
286
+ const inheritedEvidence = parseTaskArtifactOwnerDeletionEvidence(
287
+ inherited.receipt.taskArtifactOwnerDeletionEvidence,
288
+ );
289
+ if (!deepSame(inheritedEvidence, evidence)) throw new Error("task_artifact_owner_continuation_evidence_mismatch");
290
+ const inheritedOutcome = parseTaskArtifactOwnerRetirementOutcome(
291
+ authority.storageContext,
292
+ evidence,
293
+ inherited.receipt.taskArtifactOwnerRetirementOutcome,
294
+ );
295
+ if (inheritedOutcome.kind !== "completed") throw new Error("task_artifact_owner_physical_retirement_unverified");
296
+ verifyTaskArtifactOwnerPhysicalRetirement(authority.storageContext, evidence, inheritedOutcome);
297
+ authority.assertOwned();
298
+ const sharedAfterInheritance = await hasSiblingTaskArtifactOwnerTranscript(
299
+ new FileSessionStorage(),
300
+ target.path,
301
+ evidence.locator,
302
+ authority.storageContext,
303
+ authority.inspectProtocol,
304
+ );
305
+ authority.assertOwned();
306
+ if (sharedAfterInheritance)
307
+ return { state: "pending", message: "task_artifact_owner_shared_with_sibling_transcript" };
308
+ const published = await authority.publishReceipt({
309
+ ...managedGcReceiptTarget(receipt),
310
+ state: "owner_retired",
311
+ taskArtifactOwnerDeletionEvidence: evidence,
312
+ artifactsRemoved: true,
313
+ taskArtifactOwnerRetirementOutcome: inheritedOutcome,
314
+ taskArtifactOwnerRetired: true,
315
+ });
316
+ if (published.state !== "owner_retired") throw new Error("task_artifact_owner_inheritance_pending");
317
+ return { state: "owner_retired" };
318
+ }
319
+ const previous = receipt.taskArtifactOwnerRetirementOutcome;
320
+ const continuation = previous && previous.kind !== "completed" ? previous.continuation : undefined;
321
+ authority.assertOwned();
322
+ const outcome = retireTaskArtifactOwner(authority.storageContext, evidence, continuation);
323
+ authority.assertOwned();
324
+ if (outcome.kind === "completed") {
325
+ await authority.publishReceipt({
326
+ ...managedGcReceiptTarget(receipt),
327
+ state: "owner_retired",
328
+ taskArtifactOwnerDeletionEvidence: evidence,
329
+ artifactsRemoved: true,
330
+ taskArtifactOwnerRetirementOutcome: outcome,
331
+ taskArtifactOwnerRetired: true,
332
+ });
333
+ return { state: "owner_retired" };
334
+ }
335
+ await authority.publishReceipt({
336
+ ...managedGcReceiptTarget(receipt),
337
+ state: "owner_pending",
338
+ taskArtifactOwnerDeletionEvidence: evidence,
339
+ artifactsRemoved: true,
340
+ taskArtifactOwnerRetirementOutcome: outcome,
341
+ taskArtifactOwnerRetirementContinuation: outcome.continuation,
342
+ ...(outcome.kind === "payload_retired"
343
+ ? { taskArtifactOwnerPayloadRetired: true as const, taskArtifactOwnerNamespaceRetained: true as const }
344
+ : {}),
345
+ });
346
+ return outcome.kind === "payload_retired"
347
+ ? { state: "payload_retired", message: "task_artifact_owner_namespace_cleanup_pending" }
348
+ : {
349
+ state: "pending",
350
+ message: outcome.kind === "uncertain" ? outcome.reason : "task_artifact_owner_namespace_cleanup_pending",
351
+ };
352
+ }
353
+
354
+ export async function persistManagedGcStorageOwnerDisposition(
355
+ authority: ManagedGcOwnerCleanupAuthority,
356
+ target: ManagedGcOwnerCleanupTarget,
357
+ deletion: Extract<VerifiedSessionDeleteResult, { kind: "cleanup_pending"; phase: "task_artifact_owner" }>,
358
+ ): Promise<ManagedGcOwnerProgress> {
359
+ const evidence = parseTaskArtifactOwnerDeletionEvidence(deletion.taskArtifactOwnerDeletionEvidence);
360
+ if (!target.taskArtifactOwnerDeletionEvidence || !deepSame(evidence, target.taskArtifactOwnerDeletionEvidence))
361
+ throw new Error("task_artifact_owner_continuation_evidence_mismatch");
362
+ if (!deletion.artifactsRemoved) return { state: "pending", message: deletion.error.message };
363
+ const receipt = await publishManagedGcArtifactsRemoved(authority, target);
364
+ if (!receipt) throw new Error("task_artifact_owner_continuation_state_missing");
365
+ const outcomeValue = deletion.taskArtifactOwnerRetirementOutcome;
366
+ if (!outcomeValue) return { state: "pending", message: deletion.error.message };
367
+ const outcome = parseTaskArtifactOwnerRetirementOutcome(authority.storageContext, evidence, outcomeValue);
368
+ if (
369
+ (deletion.taskArtifactOwnerRetired === true) !== (outcome.kind === "completed") ||
370
+ (deletion.taskArtifactOwnerPayloadRetired === true) !== (outcome.kind === "payload_retired") ||
371
+ (deletion.taskArtifactOwnerNamespaceRetained === true) !== (outcome.kind === "payload_retired") ||
372
+ (outcome.kind !== "completed" &&
373
+ !deepSame(deletion.taskArtifactOwnerRetirementContinuation, outcome.continuation))
374
+ )
375
+ throw new Error("task_artifact_owner_retirement_outcome_mismatch");
376
+ if (outcome.kind === "completed") {
377
+ await authority.publishReceipt({
378
+ ...managedGcReceiptTarget(receipt),
379
+ state: "owner_retired",
380
+ taskArtifactOwnerDeletionEvidence: evidence,
381
+ artifactsRemoved: true,
382
+ taskArtifactOwnerRetirementOutcome: outcome,
383
+ taskArtifactOwnerRetired: true,
384
+ });
385
+ return { state: "owner_retired" };
386
+ }
387
+ await authority.publishReceipt({
388
+ ...managedGcReceiptTarget(receipt),
389
+ state: "owner_pending",
390
+ taskArtifactOwnerDeletionEvidence: evidence,
391
+ artifactsRemoved: true,
392
+ taskArtifactOwnerRetirementOutcome: outcome,
393
+ taskArtifactOwnerRetirementContinuation: outcome.continuation,
394
+ ...(outcome.kind === "payload_retired"
395
+ ? { taskArtifactOwnerPayloadRetired: true as const, taskArtifactOwnerNamespaceRetained: true as const }
396
+ : {}),
397
+ });
398
+ return outcome.kind === "payload_retired"
399
+ ? { state: "payload_retired", message: "task_artifact_owner_namespace_cleanup_pending" }
400
+ : {
401
+ state: "pending",
402
+ message: outcome.kind === "uncertain" ? outcome.reason : "task_artifact_owner_namespace_cleanup_pending",
403
+ };
404
+ }
405
+
406
+ export async function managedGcOwnerProgressBeforeDelete(
407
+ authority: ManagedGcOwnerCleanupAuthority,
408
+ target: ManagedGcOwnerCleanupTarget,
409
+ tombstoneTargets: readonly ManagedGcOwnerCleanupTarget[],
410
+ artifactsRemoved: boolean,
411
+ ): Promise<ManagedGcOwnerProgress> {
412
+ const evidence = target.taskArtifactOwnerDeletionEvidence;
413
+ if (!evidence) return { state: "none" };
414
+ const receipt = await authority.readReceipt(target.path);
415
+ if (!receipt || !deepSame(receipt.taskArtifactOwnerDeletionEvidence, evidence))
416
+ throw new Error("task_artifact_owner_continuation_state_missing");
417
+ if (receipt.state === "prepared" && !artifactsRemoved) {
418
+ authority.assertOwned();
419
+ const shared = await hasSiblingTaskArtifactOwnerTranscript(
420
+ new FileSessionStorage(),
421
+ target.path,
422
+ evidence.locator,
423
+ authority.storageContext,
424
+ authority.inspectProtocol,
425
+ );
426
+ authority.assertOwned();
427
+ return shared
428
+ ? { state: "pending", message: "task_artifact_owner_shared_with_sibling_transcript" }
429
+ : { state: "none" };
430
+ }
431
+ return retireManagedGcOwnerAfterArtifacts(authority, target, tombstoneTargets);
432
+ }
433
+
434
+ export async function taskArtifactOwnerTranscriptResult(
435
+ authority: ManagedGcOwnerCleanupAuthority,
436
+ target: ManagedGcOwnerCleanupTarget,
437
+ ): Promise<"none" | "retired" | "payload_retired"> {
438
+ if (path.dirname(target.path) !== authority.directoryPath) {
439
+ if (hasUnsupportedLegacyOwnerTarget(authority.directoryPath, target))
440
+ throw new Error("task_artifact_owner_legacy_scope_unsupported");
441
+ return "none";
442
+ }
443
+ const receipt = await authority.readReceipt(target.path);
444
+ if (!receipt) {
445
+ if (target.taskArtifactOwnerDeletionEvidence) throw new Error("task_artifact_owner_continuation_state_missing");
446
+ return "none";
447
+ }
448
+ if (!deepSame(receipt.taskArtifactOwnerDeletionEvidence, target.taskArtifactOwnerDeletionEvidence))
449
+ throw new Error("task_artifact_owner_continuation_evidence_mismatch");
450
+ if (receipt.state === "owner_retired") return "retired";
451
+ return receipt.taskArtifactOwnerRetirementOutcome?.kind === "payload_retired" ? "payload_retired" : "none";
452
+ }
453
+
454
+ export interface ManagedGcOwnerTranscriptDeleteReceipt {
455
+ readonly taskArtifactOwnerTranscriptDeleted?: true;
456
+ }
457
+
458
+ export async function persistManagedGcOwnerTranscriptDeletion<T extends ManagedGcOwnerTranscriptDeleteReceipt>(input: {
459
+ target: ManagedGcOwnerCleanupTarget;
460
+ fallback: T;
461
+ deletion: Extract<VerifiedSessionDeleteResult, { kind: "deleted" }>;
462
+ readLatest: () => T | undefined;
463
+ nextReceipt: (latest: T) => T;
464
+ publishPending: (receipt: T) => Promise<void>;
465
+ }): Promise<void> {
466
+ if (!input.target.taskArtifactOwnerDeletionEvidence) return;
467
+ if (input.deletion.taskArtifactOwnerTranscriptDeleted !== true)
468
+ throw new Error("task_artifact_owner_transcript_deletion_unverified");
469
+ const latest = input.readLatest() ?? input.fallback;
470
+ if (latest.taskArtifactOwnerTranscriptDeleted) return;
471
+ const next = input.nextReceipt(latest);
472
+ await input.publishPending({ ...next, taskArtifactOwnerTranscriptDeleted: true as const });
473
+ }