@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,245 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import type { NativeDirectoryTreeSnapshot } from "@gajae-code/natives";
4
+ import {
5
+ assertSafeRelativePath,
6
+ assertSessionRoot,
7
+ freezeTreeSnapshot,
8
+ immutableDeletionEvidence,
9
+ isOwnerRetainedRoot,
10
+ manifestRelativePath,
11
+ OWNER_DIRECTORY,
12
+ OWNER_MANIFEST,
13
+ OWNER_SCHEMA_VERSION,
14
+ ownerIdForSession,
15
+ ownerRelativePath,
16
+ parseTaskArtifactOwnerLocator,
17
+ sameOwnerParentIdentity,
18
+ type TaskArtifactOwnerDeletionEvidence,
19
+ type TaskArtifactOwnerLocator,
20
+ type TaskArtifactOwnerParentIdentity,
21
+ type TaskArtifactOwnerStorageContext,
22
+ } from "../task-artifact-owner-codec";
23
+ import { ManagedSessionDescendantStore } from "./managed-session-storage";
24
+
25
+ export interface OwnerManifest extends TaskArtifactOwnerLocator {
26
+ readonly sessionId: string;
27
+ }
28
+
29
+ function sessionRootStore(
30
+ context: TaskArtifactOwnerStorageContext,
31
+ access: "read-only" | "read-write",
32
+ ): ManagedSessionDescendantStore {
33
+ assertSessionRoot(context);
34
+ if (path.resolve(context.profileAgentDir) !== context.profileAgentDir)
35
+ throw new Error("task_artifact_owner_profile_invalid");
36
+ const profile = fs.lstatSync(context.profileAgentDir, { bigint: true });
37
+ if (!profile.isDirectory() || profile.isSymbolicLink()) throw new Error("task_artifact_owner_profile_invalid");
38
+ const stat = fs.lstatSync(context.sessionsRoot, { bigint: true });
39
+ if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error("task_artifact_owner_root_invalid");
40
+ return new ManagedSessionDescendantStore(
41
+ context.rootAuthority,
42
+ context.sessionsRoot,
43
+ undefined,
44
+ context.securityPolicy,
45
+ context.profileAgentDir,
46
+ {
47
+ canonicalPath: context.sessionsRoot,
48
+ dev: BigInt.asUintN(64, stat.dev),
49
+ ino: BigInt.asUintN(64, stat.ino),
50
+ },
51
+ access,
52
+ );
53
+ }
54
+
55
+ export function newSessionRootStore(context: TaskArtifactOwnerStorageContext): ManagedSessionDescendantStore {
56
+ return sessionRootStore(context, "read-write");
57
+ }
58
+
59
+ /** Path-backed reader with no retained or recovery-mutable native authority. */
60
+ export function newSessionRootReaderStore(context: TaskArtifactOwnerStorageContext): ManagedSessionDescendantStore {
61
+ return sessionRootStore(context, "read-only");
62
+ }
63
+
64
+ function parseOwnerManifest(bytes: Uint8Array): OwnerManifest {
65
+ let parsed: unknown;
66
+ try {
67
+ parsed = JSON.parse(Buffer.from(bytes).toString("utf8"));
68
+ } catch {
69
+ throw new Error("task_artifact_owner_manifest_invalid");
70
+ }
71
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || Object.keys(parsed).length !== 5)
72
+ throw new Error("task_artifact_owner_manifest_invalid");
73
+ const record = parsed as Record<string, unknown>;
74
+ if (typeof record.sessionId !== "string" || record.sessionId.length === 0)
75
+ throw new Error("task_artifact_owner_manifest_invalid");
76
+ let locator: TaskArtifactOwnerLocator | undefined;
77
+ try {
78
+ locator = parseTaskArtifactOwnerLocator({
79
+ schemaVersion: record.schemaVersion,
80
+ ownerId: record.ownerId,
81
+ directoryDev: record.directoryDev,
82
+ directoryIno: record.directoryIno,
83
+ });
84
+ } catch {
85
+ throw new Error("task_artifact_owner_manifest_invalid");
86
+ }
87
+ if (!locator) throw new Error("task_artifact_owner_manifest_invalid");
88
+ return { ...locator, sessionId: record.sessionId };
89
+ }
90
+
91
+ export function readOwnerManifest(
92
+ store: ManagedSessionDescendantStore,
93
+ locator: TaskArtifactOwnerLocator,
94
+ relativePath = manifestRelativePath(locator.ownerId),
95
+ ): OwnerManifest {
96
+ const manifest = store.readExpected(relativePath);
97
+ if (!manifest) throw new Error("task_artifact_owner_manifest_missing");
98
+ const parsed = parseOwnerManifest(manifest.bytes);
99
+ if (
100
+ parsed.ownerId !== locator.ownerId ||
101
+ parsed.directoryDev !== locator.directoryDev ||
102
+ parsed.directoryIno !== locator.directoryIno
103
+ )
104
+ throw new Error("task_artifact_owner_manifest_mismatch");
105
+ return parsed;
106
+ }
107
+
108
+ export function assertOwnerDirectoryExists(context: TaskArtifactOwnerStorageContext, ownerId: string): void {
109
+ const parent = path.join(context.sessionsRoot, OWNER_DIRECTORY);
110
+ const owner = path.join(parent, ownerId);
111
+ for (const candidate of [parent, owner]) {
112
+ let stat: fs.BigIntStats;
113
+ try {
114
+ stat = fs.lstatSync(candidate, { bigint: true });
115
+ } catch (error) {
116
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") throw new Error("task_artifact_owner_missing");
117
+ throw error;
118
+ }
119
+ if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error("task_artifact_owner_replaced");
120
+ }
121
+ }
122
+
123
+ export function assertOwnerIdentity(store: ManagedSessionDescendantStore, locator: TaskArtifactOwnerLocator): void {
124
+ const identity = store.subtreeRootAuthority;
125
+ if (identity.dev.toString() !== locator.directoryDev || identity.ino.toString() !== locator.directoryIno)
126
+ throw new Error("task_artifact_owner_identity_mismatch");
127
+ }
128
+
129
+ export function openOwnerStore(
130
+ context: TaskArtifactOwnerStorageContext,
131
+ rootStore: ManagedSessionDescendantStore,
132
+ locator: TaskArtifactOwnerLocator,
133
+ sessionId: string,
134
+ ): ManagedSessionDescendantStore {
135
+ if (locator.ownerId !== ownerIdForSession(sessionId)) throw new Error("task_artifact_owner_session_mismatch");
136
+ assertOwnerDirectoryExists(context, locator.ownerId);
137
+ const manifest = readOwnerManifest(rootStore, locator);
138
+ if (manifest.sessionId !== sessionId) throw new Error("task_artifact_owner_session_mismatch");
139
+ const identity = rootStore.captureDirectoryIdentity(ownerRelativePath(locator.ownerId));
140
+ if (identity.dev !== locator.directoryDev || identity.ino !== locator.directoryIno)
141
+ throw new Error("task_artifact_owner_identity_mismatch");
142
+ const ownerPath = path.join(context.sessionsRoot, ownerRelativePath(locator.ownerId));
143
+ const ownerStore = new ManagedSessionDescendantStore(
144
+ context.rootAuthority,
145
+ ownerPath,
146
+ undefined,
147
+ context.securityPolicy,
148
+ context.profileAgentDir,
149
+ {
150
+ canonicalPath: ownerPath,
151
+ dev: BigInt(locator.directoryDev),
152
+ ino: BigInt(locator.directoryIno),
153
+ },
154
+ );
155
+ try {
156
+ assertOwnerIdentity(ownerStore, locator);
157
+ const finalManifest = readOwnerManifest(ownerStore, locator, OWNER_MANIFEST);
158
+ if (finalManifest.sessionId !== sessionId) throw new Error("task_artifact_owner_session_mismatch");
159
+ return ownerStore;
160
+ } catch (error) {
161
+ ownerStore.close();
162
+ throw error;
163
+ }
164
+ }
165
+
166
+ export function locatorFromManifest(manifest: OwnerManifest): TaskArtifactOwnerLocator {
167
+ return {
168
+ schemaVersion: OWNER_SCHEMA_VERSION,
169
+ ownerId: manifest.ownerId,
170
+ directoryDev: manifest.directoryDev,
171
+ directoryIno: manifest.directoryIno,
172
+ };
173
+ }
174
+
175
+ export function captureValidatedOwnerTree(
176
+ context: TaskArtifactOwnerStorageContext,
177
+ rootStore: ManagedSessionDescendantStore,
178
+ sessionId: string,
179
+ locator: TaskArtifactOwnerLocator,
180
+ ): NativeDirectoryTreeSnapshot {
181
+ if (locator.ownerId !== ownerIdForSession(sessionId)) throw new Error("task_artifact_owner_session_mismatch");
182
+ assertOwnerDirectoryExists(context, locator.ownerId);
183
+ const manifest = readOwnerManifest(rootStore, locator);
184
+ if (manifest.sessionId !== sessionId) throw new Error("task_artifact_owner_session_mismatch");
185
+ const tree = rootStore.captureTree(ownerRelativePath(locator.ownerId));
186
+ if (tree.rootDev !== locator.directoryDev || tree.rootIno !== locator.directoryIno)
187
+ throw new Error("task_artifact_owner_identity_mismatch");
188
+ return tree;
189
+ }
190
+
191
+ export function captureOwnerTreeIfPresent(
192
+ context: TaskArtifactOwnerStorageContext,
193
+ rootStore: ManagedSessionDescendantStore,
194
+ ownerId: string,
195
+ pathname: string,
196
+ ): NativeDirectoryTreeSnapshot | undefined {
197
+ if (!isOwnerRetainedRoot(context, ownerId, pathname))
198
+ throw new Error("task_artifact_owner_retained_root_unrecognized");
199
+ let named: fs.BigIntStats;
200
+ try {
201
+ named = fs.lstatSync(pathname, { bigint: true });
202
+ } catch (error) {
203
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return undefined;
204
+ throw error;
205
+ }
206
+ if (!named.isDirectory() || named.isSymbolicLink()) throw new Error("task_artifact_owner_retained_root_replaced");
207
+ const relative = path.relative(context.sessionsRoot, pathname).split(path.sep).join("/");
208
+ assertSafeRelativePath(relative);
209
+ return freezeTreeSnapshot(rootStore.captureTree(relative));
210
+ }
211
+
212
+ export function ownerTreeHasPendingManagedPublication(snapshot: NativeDirectoryTreeSnapshot): boolean {
213
+ return snapshot.entries.some(entry =>
214
+ /^\..+\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(?:staging|replacement)$/u.test(
215
+ path.posix.basename(entry.relativePath),
216
+ ),
217
+ );
218
+ }
219
+
220
+ /** Capture exact owner evidence without repairing its security, timestamps, or namespace. */
221
+ export function captureTaskArtifactOwnerDeletionEvidence(
222
+ context: TaskArtifactOwnerStorageContext,
223
+ sessionId: string,
224
+ locatorValue: unknown,
225
+ ): TaskArtifactOwnerDeletionEvidence | undefined {
226
+ const locator = parseTaskArtifactOwnerLocator(locatorValue);
227
+ if (!locator) return undefined;
228
+ const rootStore = newSessionRootReaderStore(context);
229
+ try {
230
+ rootStore.verifyRootSecurity();
231
+ const parentIdentity: TaskArtifactOwnerParentIdentity = rootStore.captureDirectoryIdentity(OWNER_DIRECTORY);
232
+ const treeSnapshot = captureValidatedOwnerTree(context, rootStore, sessionId, locator);
233
+ // This refuses to capture during publication; it does not revoke independent open descriptors.
234
+ if (ownerTreeHasPendingManagedPublication(treeSnapshot))
235
+ throw new Error("task_artifact_owner_writer_not_quiescent");
236
+ const finalManifest = readOwnerManifest(rootStore, locator);
237
+ if (finalManifest.sessionId !== sessionId) throw new Error("task_artifact_owner_session_mismatch");
238
+ const parentAfter = rootStore.captureDirectoryIdentity(OWNER_DIRECTORY);
239
+ if (!sameOwnerParentIdentity(parentIdentity, parentAfter))
240
+ throw new Error("task_artifact_owner_parent_changed_during_capture");
241
+ return immutableDeletionEvidence(sessionId, locator, parentIdentity, treeSnapshot);
242
+ } finally {
243
+ rootStore.close();
244
+ }
245
+ }