niceeval 0.16.3-canary.99 → 0.17.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 (258) hide show
  1. package/dist/cli/bootstrap.cjs +7 -1
  2. package/dist/cli/bootstrap.cjs.map +1 -1
  3. package/dist/cli/project-configuration.cjs +8 -11
  4. package/dist/cli/project-configuration.cjs.map +1 -1
  5. package/dist/expect/index.cjs.map +1 -1
  6. package/dist/expect/index.d.cts +1 -0
  7. package/dist/expect/index.d.mts +1 -0
  8. package/dist/expect/index.d.ts +1 -0
  9. package/dist/experiment/host/cli/contribution.cjs +6 -11
  10. package/dist/experiment/host/cli/contribution.cjs.map +1 -1
  11. package/dist/experiment/host/cli/contribution.d.cts +0 -16
  12. package/dist/experiment/host/cli/contribution.d.mts +0 -16
  13. package/dist/experiment/host/cli/contribution.d.ts +0 -16
  14. package/dist/experiment/host/operations.cjs +3 -3
  15. package/dist/experiment/host/operations.cjs.map +1 -1
  16. package/dist/experiment/host/types.cjs.map +1 -1
  17. package/dist/experiment/host/types.d.cts +0 -4
  18. package/dist/experiment/host/types.d.mts +0 -4
  19. package/dist/experiment/host/types.d.ts +0 -4
  20. package/dist/fresh-import.cjs +2 -2
  21. package/dist/fresh-import.cjs.map +1 -1
  22. package/dist/fresh-import.d.cts +3 -3
  23. package/dist/fresh-import.d.mts +3 -3
  24. package/dist/fresh-import.d.ts +3 -3
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +1 -0
  27. package/dist/index.d.mts +1 -0
  28. package/dist/index.d.ts +1 -0
  29. package/dist/inspection/codec.cjs.map +1 -1
  30. package/dist/inspection/codec.d.cts +1 -1
  31. package/dist/inspection/codec.d.mts +1 -1
  32. package/dist/inspection/codec.d.ts +1 -1
  33. package/dist/inspection/facts.cjs +66 -9
  34. package/dist/inspection/facts.cjs.map +1 -1
  35. package/dist/inspection/facts.d.cts +4 -0
  36. package/dist/inspection/facts.d.mts +4 -0
  37. package/dist/inspection/facts.d.ts +4 -0
  38. package/dist/inspection/facts.js +4 -2
  39. package/dist/inspection/index.cjs +1 -3
  40. package/dist/inspection/index.cjs.map +1 -1
  41. package/dist/inspection/index.d.cts +1 -1
  42. package/dist/inspection/index.d.mts +1 -1
  43. package/dist/inspection/index.d.ts +1 -1
  44. package/dist/inspection/index.js +44 -48
  45. package/dist/inspection/limits.cjs +3 -1
  46. package/dist/inspection/limits.cjs.map +1 -1
  47. package/dist/inspection/limits.d.cts +2 -0
  48. package/dist/inspection/limits.d.mts +2 -0
  49. package/dist/inspection/limits.d.ts +2 -0
  50. package/dist/inspection/limits.js +6 -4
  51. package/dist/inspection/project-source.cjs +4 -1
  52. package/dist/inspection/project-source.cjs.map +1 -1
  53. package/dist/inspection/protocol.cjs +10 -18
  54. package/dist/inspection/protocol.cjs.map +1 -1
  55. package/dist/inspection/protocol.d.cts +111 -173
  56. package/dist/inspection/protocol.d.mts +111 -173
  57. package/dist/inspection/protocol.d.ts +111 -173
  58. package/dist/inspection/public.mjs +73 -109
  59. package/dist/inspection/results.cjs +12 -48
  60. package/dist/inspection/results.cjs.map +1 -1
  61. package/dist/inspection/results.d.cts +124 -122
  62. package/dist/inspection/results.d.mts +124 -122
  63. package/dist/inspection/results.d.ts +124 -122
  64. package/dist/inspection/results.js +16 -20
  65. package/dist/inspection/select.cjs +80 -117
  66. package/dist/inspection/select.cjs.map +1 -1
  67. package/dist/inspection/source.cjs +14 -15
  68. package/dist/inspection/source.cjs.map +1 -1
  69. package/dist/inspection/source.d.cts +6 -3
  70. package/dist/inspection/source.d.mts +6 -3
  71. package/dist/inspection/source.d.ts +6 -3
  72. package/dist/inspection/trace.cjs +1 -1
  73. package/dist/inspection/trace.cjs.map +1 -1
  74. package/dist/load-config.cjs +17 -11
  75. package/dist/load-config.cjs.map +1 -1
  76. package/dist/load-config.d.cts +3 -2
  77. package/dist/load-config.d.mts +3 -2
  78. package/dist/load-config.d.ts +3 -2
  79. package/dist/o11y/adapter-usage-projection.cjs +5 -1
  80. package/dist/o11y/adapter-usage-projection.cjs.map +1 -1
  81. package/dist/o11y/adapter-usage-projection.d.cts +109 -1
  82. package/dist/o11y/adapter-usage-projection.d.mts +109 -1
  83. package/dist/o11y/adapter-usage-projection.d.ts +109 -1
  84. package/dist/o11y/cache-read.cjs +113 -0
  85. package/dist/o11y/cache-read.cjs.map +1 -0
  86. package/dist/o11y/cache-read.d.cts +80 -0
  87. package/dist/o11y/cache-read.d.mts +80 -0
  88. package/dist/o11y/cache-read.d.ts +80 -0
  89. package/dist/o11y/cache-read.js +8 -0
  90. package/dist/o11y/cache-read.js.map +1 -0
  91. package/dist/o11y/eval-usage.cjs +4 -1
  92. package/dist/o11y/eval-usage.cjs.map +1 -1
  93. package/dist/o11y/eval-usage.d.cts +4 -1
  94. package/dist/o11y/eval-usage.d.mts +4 -1
  95. package/dist/o11y/eval-usage.d.ts +4 -1
  96. package/dist/record/host/sqlite-host.cjs +188 -53
  97. package/dist/record/host/sqlite-host.cjs.map +1 -1
  98. package/dist/record/host/sqlite-host.d.cts +37 -1
  99. package/dist/record/host/sqlite-host.d.mts +37 -1
  100. package/dist/record/host/sqlite-host.d.ts +37 -1
  101. package/dist/record/host/sqlite-host.js +16 -8
  102. package/dist/record/maintenance/runtime.cjs +3 -3
  103. package/dist/record/maintenance/runtime.cjs.map +1 -1
  104. package/dist/record/sqlite/admission-repository.cjs +18 -18
  105. package/dist/record/sqlite/admission-repository.cjs.map +1 -1
  106. package/dist/record/sqlite/case-repository.cjs +6 -6
  107. package/dist/record/sqlite/case-repository.cjs.map +1 -1
  108. package/dist/record/sqlite/coordination-repository.cjs +25 -25
  109. package/dist/record/sqlite/coordination-repository.cjs.map +1 -1
  110. package/dist/record/sqlite/current-schema.cjs +115 -111
  111. package/dist/record/sqlite/current-schema.cjs.map +1 -1
  112. package/dist/record/sqlite/current-schema.d.cts +3 -3
  113. package/dist/record/sqlite/current-schema.d.mts +3 -3
  114. package/dist/record/sqlite/current-schema.d.ts +3 -3
  115. package/dist/record/sqlite/database.cjs +56 -53
  116. package/dist/record/sqlite/database.cjs.map +1 -1
  117. package/dist/record/sqlite/index.cjs +3 -1
  118. package/dist/record/sqlite/index.cjs.map +1 -1
  119. package/dist/record/sqlite/index.d.cts +5 -2
  120. package/dist/record/sqlite/index.d.mts +5 -2
  121. package/dist/record/sqlite/index.d.ts +5 -2
  122. package/dist/record/sqlite/legacy-schema-018.cjs +443 -0
  123. package/dist/record/sqlite/legacy-schema-018.cjs.map +1 -0
  124. package/dist/record/sqlite/legacy-schema-018.d.cts +6 -0
  125. package/dist/record/sqlite/legacy-schema-018.d.mts +6 -0
  126. package/dist/record/sqlite/legacy-schema-018.d.ts +6 -0
  127. package/dist/record/sqlite/legacy-schema-018.js +6 -0
  128. package/dist/record/sqlite/legacy-schema-018.js.map +1 -0
  129. package/dist/record/sqlite/migration.cjs +105 -46
  130. package/dist/record/sqlite/migration.cjs.map +1 -1
  131. package/dist/record/sqlite/migration.d.cts +2 -1
  132. package/dist/record/sqlite/migration.d.mts +2 -1
  133. package/dist/record/sqlite/migration.d.ts +2 -1
  134. package/dist/record/sqlite/portable-capture.cjs +13 -13
  135. package/dist/record/sqlite/portable-capture.cjs.map +1 -1
  136. package/dist/record/sqlite/registry-repository.cjs +22 -22
  137. package/dist/record/sqlite/registry-repository.cjs.map +1 -1
  138. package/dist/record/sqlite/schema.cjs +10 -2
  139. package/dist/record/sqlite/schema.cjs.map +1 -1
  140. package/dist/record/sqlite/schema.d.cts +4 -1
  141. package/dist/record/sqlite/schema.d.mts +4 -1
  142. package/dist/record/sqlite/schema.d.ts +4 -1
  143. package/dist/record/sqlite/schema.js +20 -14
  144. package/dist/record/sqlite/storage-worker.cjs +1 -1
  145. package/dist/record/sqlite/storage-worker.cjs.map +1 -1
  146. package/dist/record/sqlite/storage.cjs +316 -232
  147. package/dist/record/sqlite/storage.cjs.map +1 -1
  148. package/dist/record/sqlite/storage.d.cts +10 -2
  149. package/dist/record/sqlite/storage.d.mts +10 -2
  150. package/dist/record/sqlite/storage.d.ts +10 -2
  151. package/dist/record/sqlite/storage.js +54 -50
  152. package/dist/record/sqlite/types.cjs +1 -1
  153. package/dist/record/sqlite/types.cjs.map +1 -1
  154. package/dist/record/sqlite/types.d.cts +13 -1
  155. package/dist/record/sqlite/types.d.mts +13 -1
  156. package/dist/record/sqlite/types.d.ts +13 -1
  157. package/dist/run/cli/contribution.cjs +17 -12
  158. package/dist/run/cli/contribution.cjs.map +1 -1
  159. package/dist/run/host/lifecycle-adapter.cjs +1 -1
  160. package/dist/run/host/lifecycle-adapter.cjs.map +1 -1
  161. package/dist/run/storage/owner-identity.cjs +78 -16
  162. package/dist/run/storage/owner-identity.cjs.map +1 -1
  163. package/dist/run/storage/owner-identity.d.cts +2 -1
  164. package/dist/run/storage/owner-identity.d.mts +2 -1
  165. package/dist/run/storage/owner-identity.d.ts +2 -1
  166. package/dist/run/storage/sqlite.cjs +55 -55
  167. package/dist/run/storage/sqlite.cjs.map +1 -1
  168. package/dist/runner/accept.cjs +12 -42
  169. package/dist/runner/accept.cjs.map +1 -1
  170. package/dist/runner/accept.d.cts +2 -3
  171. package/dist/runner/accept.d.mts +2 -3
  172. package/dist/runner/accept.d.ts +2 -3
  173. package/dist/runner/adapter-usage.cjs +2 -2
  174. package/dist/runner/adapter-usage.cjs.map +1 -1
  175. package/dist/runner/adoption.cjs +14 -26
  176. package/dist/runner/adoption.cjs.map +1 -1
  177. package/dist/runner/adoption.d.cts +5 -13
  178. package/dist/runner/adoption.d.mts +5 -13
  179. package/dist/runner/adoption.d.ts +5 -13
  180. package/dist/runner/adoption.js +2 -4
  181. package/dist/runner/record.cjs +24 -18
  182. package/dist/runner/record.cjs.map +1 -1
  183. package/dist/runner/rename-experiment.cjs +5 -7
  184. package/dist/runner/rename-experiment.cjs.map +1 -1
  185. package/dist/runner/reuse-plan.cjs +37 -18
  186. package/dist/runner/reuse-plan.cjs.map +1 -1
  187. package/dist/runner/reuse-plan.d.cts +4 -1
  188. package/dist/runner/reuse-plan.d.mts +4 -1
  189. package/dist/runner/reuse-plan.d.ts +4 -1
  190. package/dist/runner/setup-prefix-plan.cjs +17 -12
  191. package/dist/runner/setup-prefix-plan.cjs.map +1 -1
  192. package/dist/runner/setup-prefix-plan.d.cts +0 -2
  193. package/dist/runner/setup-prefix-plan.d.mts +0 -2
  194. package/dist/runner/setup-prefix-plan.d.ts +0 -2
  195. package/dist/runner/setup-prefix-plan.js +8 -12
  196. package/dist/sandbox/backend.cjs +10 -1
  197. package/dist/sandbox/backend.cjs.map +1 -1
  198. package/dist/sandbox/backend.d.cts +16 -8
  199. package/dist/sandbox/backend.d.mts +16 -8
  200. package/dist/sandbox/backend.d.ts +16 -8
  201. package/dist/sandbox/backend.js +28 -26
  202. package/dist/sandbox/docker.cjs +7 -1
  203. package/dist/sandbox/docker.cjs.map +1 -1
  204. package/dist/sandbox/e2b-cache-repository.cjs +13 -3
  205. package/dist/sandbox/e2b-cache-repository.cjs.map +1 -1
  206. package/dist/sandbox/e2b-cache-repository.d.cts +3 -0
  207. package/dist/sandbox/e2b-cache-repository.d.mts +3 -0
  208. package/dist/sandbox/e2b-cache-repository.d.ts +3 -0
  209. package/dist/sandbox/e2b-cache-repository.js +16 -12
  210. package/dist/sandbox/e2b.cjs +2 -2
  211. package/dist/sandbox/e2b.cjs.map +1 -1
  212. package/dist/sandbox/incus/materialize.cjs +1 -1
  213. package/dist/sandbox/incus/materialize.cjs.map +1 -1
  214. package/dist/show/contribution.cjs +3 -3
  215. package/dist/show/contribution.cjs.map +1 -1
  216. package/dist/show/model.cjs +14 -13
  217. package/dist/show/model.cjs.map +1 -1
  218. package/dist/show/model.d.cts +7 -7
  219. package/dist/show/model.d.mts +7 -7
  220. package/dist/show/model.d.ts +7 -7
  221. package/dist/show/render.cjs +14 -0
  222. package/dist/show/render.cjs.map +1 -1
  223. package/dist/user-database/storage-worker.cjs +13 -3
  224. package/dist/user-database/storage-worker.cjs.map +1 -1
  225. package/dist/view/app-dist/.vite/manifest.json +2 -2
  226. package/dist/view/app-dist/assets/{index-CmVoXbwG.js → index-B3ijZRph.js} +17 -17
  227. package/dist/view/app-dist/assets/{quality-cost-scatter-BuLISaH4.js → quality-cost-scatter-B--DfJ9s.js} +1 -1
  228. package/dist/view/app-dist/index.html +1 -1
  229. package/dist/view/application-runtime.cjs +8 -0
  230. package/dist/view/application-runtime.cjs.map +1 -0
  231. package/dist/view/application-runtime.d.cts +9 -0
  232. package/dist/view/application-runtime.d.mts +9 -0
  233. package/dist/view/application-runtime.d.ts +9 -0
  234. package/dist/view/application-runtime.js +6 -0
  235. package/dist/view/application-runtime.js.map +1 -0
  236. package/dist/view/cli/contribution.cjs +5 -2
  237. package/dist/view/cli/contribution.cjs.map +1 -1
  238. package/dist/view/cli/contribution.d.cts +2 -1
  239. package/dist/view/cli/contribution.d.mts +2 -1
  240. package/dist/view/cli/contribution.d.ts +2 -1
  241. package/dist/view/function-runtime.mjs +1019 -456
  242. package/dist/view/http-protocol.d.cts +1 -9
  243. package/dist/view/http-protocol.d.mts +1 -9
  244. package/dist/view/http-protocol.d.ts +1 -9
  245. package/dist/view/inspection-host.cjs +39 -30
  246. package/dist/view/inspection-host.cjs.map +1 -1
  247. package/dist/view/inspection-host.d.cts +7545 -2
  248. package/dist/view/inspection-host.d.mts +7545 -2
  249. package/dist/view/inspection-host.d.ts +7545 -2
  250. package/dist/view/server.cjs +8 -5
  251. package/dist/view/server.cjs.map +1 -1
  252. package/dist/view/server.d.cts +4 -2
  253. package/dist/view/server.d.mts +4 -2
  254. package/dist/view/server.d.ts +4 -2
  255. package/docs-site/zh/reference/cli.mdx +1 -2
  256. package/docs-site/zh/tutorials/control-run-cost.mdx +22 -0
  257. package/docs-site/zh/tutorials/niceeval-taste-application.mdx +21 -0
  258. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-adapter.js","sourceRoot":"","sources":["lifecycle-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { DateTime, Effect } from \"effect\";\nimport type { ProjectStateDatabase } from \"../../record/sqlite/project-state-database.ts\";\nimport { SqliteRecordError } from \"../../record/sqlite/errors.ts\";\nimport { currentPublicationCutoff, deleteRunResource, observeRunWriterTermination, readRunResource, recoverRunResource, RunStorageError, } from \"../storage/index.ts\";\nimport type { RunDeleteReceipt, RunRecoverReceipt, } from \"./types.ts\";\nimport { RunDeleteError, RunRecoverError, } from \"./types.ts\";\n/**\n * Narrow wiring seam for the Run-owned SQLite adapter. The current Record\n * runtime cannot yet delete terminal Runs or fence and recover an active\n * writer, so the public Host fails closed instead of rebranding `clean`.\n */\nexport interface RunLifecycleAdapter {\n readonly delete: (request: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.Effect<RunDeleteReceipt, RunDeleteError, ProjectStateDatabase>;\n readonly recover: (request: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.Effect<RunRecoverReceipt, RunRecoverError, ProjectStateDatabase>;\n}\nfunction storageRoot(cwd: string): string {\n return resolve(cwd, \".niceeval\");\n}\nfunction databaseExists(root: string): boolean {\n return existsSync(resolve(root, \"record.sqlite\"));\n}\nfunction deleteFailure(runId: string, cause: unknown): RunDeleteError {\n if (cause instanceof RunDeleteError)\n return cause;\n if (cause instanceof SqliteRecordError && cause.cause instanceof Error && cause.cause.name === \"run-delete-reference-conflict\") {\n const details = Reflect.get(cause.cause, \"details\");\n if (Array.isArray(details)) {\n const dependencies = details as RunStorageError[\"dependencies\"];\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-referenced\",\n message: `Run ${runId} is referenced by ${dependencies.length} published Attempt binding(s): ${dependencies.map((dependency) => `${dependency.dependentRunId}/${dependency.dependentSlotId} -> ${dependency.attemptLocator}`).join(\", \")}.`,\n cause,\n });\n }\n }\n if (cause instanceof RunStorageError) {\n if (cause.code === \"run-not-found\") {\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n cause,\n });\n }\n if (cause.code === \"run-delete-reference-conflict\") {\n const dependencies = cause.dependencies.map((dependency) => `${dependency.dependentRunId}/${dependency.dependentSlotId} -> ${dependency.attemptLocator}`).join(\", \");\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-referenced\",\n message: `Run ${runId} is referenced by ${cause.dependencies.length} published Attempt binding(s): ${dependencies}.`,\n cause,\n });\n }\n }\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-delete-failed\",\n message: cause instanceof Error ? cause.message : `Run ${runId} could not be deleted.`,\n cause,\n });\n}\nfunction recoverFailure(runId: string, cause: unknown): RunRecoverError {\n if (cause instanceof RunRecoverError)\n return cause;\n if (cause instanceof RunStorageError) {\n if (cause.code === \"run-not-found\") {\n return new RunRecoverError({\n operation: \"recover\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n cause,\n });\n }\n if (cause.code === \"run-not-active\" || cause.code === \"writer-generation-mismatch\") {\n return new RunRecoverError({\n operation: \"recover\",\n code: \"run-recover-failed\",\n message: `Run ${runId} changed before recovery could fence its writer.`,\n cause,\n });\n }\n }\n return new RunRecoverError({\n operation: \"recover\",\n code: \"run-recover-failed\",\n message: cause instanceof Error ? cause.message : `Run ${runId} could not be recovered.`,\n cause,\n });\n}\nexport const sqliteRunLifecycleAdapter: RunLifecycleAdapter = Object.freeze({\n delete: ({ cwd, runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => {\n const root = storageRoot(cwd);\n if (!databaseExists(root)) {\n return Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n return Effect.flatMap(DateTime.now, (now) => Effect.gen(function* () {\n const cutoff = yield* currentPublicationCutoff(root);\n const run = yield* readRunResource(root, runId, cutoff);\n if (run === undefined) {\n return yield* Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n if (run.state === \"active\") {\n return yield* Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-active\",\n message: `Run ${runId} is active and cannot be deleted.`,\n }));\n }\n yield* deleteRunResource(root, {\n runId,\n expectedState: run.state,\n deletedAt: DateTime.formatIso(now),\n deadlineEpochMs: DateTime.toEpochMillis(now) + 30000,\n });\n return Object.freeze({ runId, state: \"deleted\" as const });\n }).pipe(Effect.mapError((cause) => deleteFailure(runId, cause))));\n },\n recover: ({ cwd, runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => {\n const root = storageRoot(cwd);\n if (!databaseExists(root)) {\n return Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n return Effect.flatMap(DateTime.now, (now) => Effect.gen(function* () {\n const cutoff = yield* currentPublicationCutoff(root);\n const run = yield* readRunResource(root, runId, cutoff);\n if (run === undefined) {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n if (run.state !== \"active\") {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-terminal\",\n message: `Run ${runId} is already ${run.state}.`,\n }));\n }\n const observation = observeRunWriterTermination(run.writerGeneration);\n if (observation.state === \"active\") {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-owner-active\",\n message: `Run ${runId} still has a live writer; recovery is refused.`,\n }));\n }\n if (observation.state === \"unproven\") {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-owner-termination-unproven\",\n message: `Run ${runId} recovery requires verified owner-termination evidence.`,\n }));\n }\n yield* recoverRunResource(root, {\n runId,\n expectedWriterGeneration: run.writerGeneration,\n recoveryWriterGeneration: `recovery-v1:${randomUUID()}`,\n completedAt: DateTime.formatIso(now),\n evidence: {\n kind: \"local-linux-process-terminated-v1\",\n identity: observation.evidenceIdentity,\n observedAt: DateTime.formatIso(now),\n },\n deadlineEpochMs: DateTime.toEpochMillis(now) + 30000,\n });\n return Object.freeze({ runId, state: \"interrupted\" as const });\n }).pipe(Effect.mapError((cause) => recoverFailure(runId, cause))));\n },\n});\nexport const unavailableRunLifecycleAdapter: RunLifecycleAdapter = Object.freeze({\n delete: ({ runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-lifecycle-adapter-unavailable\",\n message: `Run ${runId} cannot be deleted because the Run lifecycle adapter is not installed.`,\n })),\n recover: ({ runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-lifecycle-adapter-unavailable\",\n message: `Run ${runId} cannot be recovered because the Run lifecycle adapter is not installed.`,\n })),\n});\n"]}
1
+ {"version":3,"file":"lifecycle-adapter.js","sourceRoot":"","sources":["lifecycle-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { DateTime, Effect } from \"effect\";\nimport type { ProjectStateDatabase } from \"../../record/sqlite/project-state-database.ts\";\nimport { SqliteRecordError } from \"../../record/sqlite/errors.ts\";\nimport { currentPublicationCutoff, deleteRunResource, observeRunWriterTermination, readRunResource, recoverRunResource, RunStorageError, } from \"../storage/index.ts\";\nimport type { RunDeleteReceipt, RunRecoverReceipt, } from \"./types.ts\";\nimport { RunDeleteError, RunRecoverError, } from \"./types.ts\";\n/**\n * Narrow wiring seam for the Run-owned SQLite adapter. The current Record\n * runtime cannot yet delete terminal Runs or fence and recover an active\n * writer, so the public Host fails closed instead of rebranding `clean`.\n */\nexport interface RunLifecycleAdapter {\n readonly delete: (request: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.Effect<RunDeleteReceipt, RunDeleteError, ProjectStateDatabase>;\n readonly recover: (request: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.Effect<RunRecoverReceipt, RunRecoverError, ProjectStateDatabase>;\n}\nfunction storageRoot(cwd: string): string {\n return resolve(cwd, \".niceeval\");\n}\nfunction databaseExists(root: string): boolean {\n return existsSync(resolve(root, \"record.sqlite\"));\n}\nfunction deleteFailure(runId: string, cause: unknown): RunDeleteError {\n if (cause instanceof RunDeleteError)\n return cause;\n if (cause instanceof SqliteRecordError && cause.cause instanceof Error && cause.cause.name === \"run-delete-reference-conflict\") {\n const details = Reflect.get(cause.cause, \"details\");\n if (Array.isArray(details)) {\n const dependencies = details as RunStorageError[\"dependencies\"];\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-referenced\",\n message: `Run ${runId} is referenced by ${dependencies.length} published Attempt binding(s): ${dependencies.map((dependency) => `${dependency.dependentRunId}/${dependency.dependentSlotId} -> ${dependency.attemptLocator}`).join(\", \")}.`,\n cause,\n });\n }\n }\n if (cause instanceof RunStorageError) {\n if (cause.code === \"run-not-found\") {\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n cause,\n });\n }\n if (cause.code === \"run-delete-reference-conflict\") {\n const dependencies = cause.dependencies.map((dependency) => `${dependency.dependentRunId}/${dependency.dependentSlotId} -> ${dependency.attemptLocator}`).join(\", \");\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-referenced\",\n message: `Run ${runId} is referenced by ${cause.dependencies.length} published Attempt binding(s): ${dependencies}.`,\n cause,\n });\n }\n }\n return new RunDeleteError({\n operation: \"delete\",\n code: \"run-delete-failed\",\n message: cause instanceof Error ? cause.message : `Run ${runId} could not be deleted.`,\n cause,\n });\n}\nfunction recoverFailure(runId: string, cause: unknown): RunRecoverError {\n if (cause instanceof RunRecoverError)\n return cause;\n if (cause instanceof RunStorageError) {\n if (cause.code === \"run-not-found\") {\n return new RunRecoverError({\n operation: \"recover\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n cause,\n });\n }\n if (cause.code === \"run-not-active\" || cause.code === \"writer-generation-mismatch\") {\n return new RunRecoverError({\n operation: \"recover\",\n code: \"run-recover-failed\",\n message: `Run ${runId} changed before recovery could fence its writer.`,\n cause,\n });\n }\n }\n return new RunRecoverError({\n operation: \"recover\",\n code: \"run-recover-failed\",\n message: cause instanceof Error ? cause.message : `Run ${runId} could not be recovered.`,\n cause,\n });\n}\nexport const sqliteRunLifecycleAdapter: RunLifecycleAdapter = Object.freeze({\n delete: ({ cwd, runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => {\n const root = storageRoot(cwd);\n if (!databaseExists(root)) {\n return Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n return Effect.flatMap(DateTime.now, (now) => Effect.gen(function* () {\n const cutoff = yield* currentPublicationCutoff(root);\n const run = yield* readRunResource(root, runId, cutoff);\n if (run === undefined) {\n return yield* Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n if (run.state === \"active\") {\n return yield* Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-active\",\n message: `Run ${runId} is active and cannot be deleted.`,\n }));\n }\n yield* deleteRunResource(root, {\n runId,\n expectedState: run.state,\n deletedAt: DateTime.formatIso(now),\n deadlineEpochMs: DateTime.toEpochMillis(now) + 30000,\n });\n return Object.freeze({ runId, state: \"deleted\" as const });\n }).pipe(Effect.mapError((cause) => deleteFailure(runId, cause))));\n },\n recover: ({ cwd, runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => {\n const root = storageRoot(cwd);\n if (!databaseExists(root)) {\n return Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n return Effect.flatMap(DateTime.now, (now) => Effect.gen(function* () {\n const cutoff = yield* currentPublicationCutoff(root);\n const run = yield* readRunResource(root, runId, cutoff);\n if (run === undefined) {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-not-found\",\n message: `Run ${runId} was not found.`,\n }));\n }\n if (run.state !== \"active\") {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-terminal\",\n message: `Run ${runId} is already ${run.state}.`,\n }));\n }\n const observation = observeRunWriterTermination(run.writerGeneration);\n if (observation.state === \"active\") {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-owner-active\",\n message: `Run ${runId} still has a live writer; recovery is refused.`,\n }));\n }\n if (observation.state === \"unproven\") {\n return yield* Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-owner-termination-unproven\",\n message: `Run ${runId} recovery requires verified owner-termination evidence.`,\n }));\n }\n yield* recoverRunResource(root, {\n runId,\n expectedWriterGeneration: run.writerGeneration,\n recoveryWriterGeneration: `recovery-v1:${randomUUID()}`,\n completedAt: DateTime.formatIso(now),\n evidence: {\n kind: observation.evidenceKind,\n identity: observation.evidenceIdentity,\n observedAt: DateTime.formatIso(now),\n },\n deadlineEpochMs: DateTime.toEpochMillis(now) + 30000,\n });\n return Object.freeze({ runId, state: \"interrupted\" as const });\n }).pipe(Effect.mapError((cause) => recoverFailure(runId, cause))));\n },\n});\nexport const unavailableRunLifecycleAdapter: RunLifecycleAdapter = Object.freeze({\n delete: ({ runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.fail(new RunDeleteError({\n operation: \"delete\",\n code: \"run-lifecycle-adapter-unavailable\",\n message: `Run ${runId} cannot be deleted because the Run lifecycle adapter is not installed.`,\n })),\n recover: ({ runId }: {\n readonly cwd: string;\n readonly runId: string;\n }) => Effect.fail(new RunRecoverError({\n operation: \"recover\",\n code: \"run-lifecycle-adapter-unavailable\",\n message: `Run ${runId} cannot be recovered because the Run lifecycle adapter is not installed.`,\n })),\n});\n"]}
@@ -3,9 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createRunWriterGeneration = createRunWriterGeneration;
4
4
  exports.observeRunWriterTermination = observeRunWriterTermination;
5
5
  const node_fs_1 = require("node:fs");
6
+ const node_child_process_1 = require("node:child_process");
6
7
  const effect_1 = require("effect");
7
8
  const VERIFIED_WRITER_PREFIX = "local-linux-process-v1:";
9
+ const DARWIN_WRITER_PREFIX = "local-darwin-process-v1:";
8
10
  const OPAQUE_WRITER_PREFIX = "opaque-writer-v1:";
11
+ const DARWIN_PROCESS_DOMAIN = "darwin-host";
9
12
  const VerifiedWriterIdentitySchema = effect_1.Schema.Struct({
10
13
  machineId: effect_1.Schema.String,
11
14
  bootId: effect_1.Schema.String,
@@ -45,14 +48,65 @@ function linuxProcessStart(pid) {
45
48
  }
46
49
  return processStart;
47
50
  }
51
+ function darwinCommand(command, args) {
52
+ return (0, node_child_process_1.execFileSync)(command, args, {
53
+ encoding: "utf8",
54
+ env: { ...process.env, LC_ALL: "C", TZ: "UTC" },
55
+ timeout: 5000,
56
+ maxBuffer: 1024 * 1024,
57
+ stdio: ["ignore", "pipe", "pipe"],
58
+ }).trim();
59
+ }
60
+ function darwinUuid(value) {
61
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(value)) {
62
+ throw new Error("Darwin system identity is malformed");
63
+ }
64
+ return value.toLowerCase();
65
+ }
66
+ function darwinMachineId() {
67
+ const platform = darwinCommand("/usr/sbin/ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"]);
68
+ const matches = [...platform.matchAll(/"IOPlatformUUID"\s*=\s*"([^"]+)"/gu)];
69
+ if (matches.length !== 1)
70
+ throw new Error("Darwin platform identity is unavailable");
71
+ return darwinUuid(matches[0][1]);
72
+ }
73
+ function darwinBootId() {
74
+ return darwinUuid(darwinCommand("/usr/sbin/sysctl", ["-n", "kern.bootsessionuuid"]));
75
+ }
76
+ /** ps lstart reads the kernel process start time, rendered to seconds in a fixed locale/zone. */
77
+ function darwinProcessStart(pid) {
78
+ let value;
79
+ try {
80
+ value = darwinCommand("/bin/ps", ["-p", String(pid), "-o", "lstart="]);
81
+ }
82
+ catch (cause) {
83
+ const failure = cause;
84
+ // ps exits 1 without diagnostics when the requested pid does not exist.
85
+ // Permission, launch, timeout, signal and parse failures cannot prove termination.
86
+ if (failure.status === 1 && failure.signal == null && failure.stdout === "" && failure.stderr === "") {
87
+ return undefined;
88
+ }
89
+ throw cause;
90
+ }
91
+ if (!/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d{2}:\d{2}:\d{2} \d{4}$/u.test(value) ||
92
+ !Number.isFinite(Date.parse(`${value} UTC`))) {
93
+ throw new Error("Darwin process start identity is malformed");
94
+ }
95
+ return value;
96
+ }
97
+ function verifiedPrefix() {
98
+ return process.platform === "linux" ? VERIFIED_WRITER_PREFIX
99
+ : process.platform === "darwin" ? DARWIN_WRITER_PREFIX : undefined;
100
+ }
48
101
  function encodeVerified(identity) {
49
- return `${VERIFIED_WRITER_PREFIX}${Buffer.from(JSON.stringify(identity), "utf8").toString("base64url")}`;
102
+ return `${verifiedPrefix()}${Buffer.from(JSON.stringify(identity), "utf8").toString("base64url")}`;
50
103
  }
51
104
  function decodeVerified(value) {
52
- if (!value.startsWith(VERIFIED_WRITER_PREFIX))
105
+ const prefix = verifiedPrefix();
106
+ if (prefix === undefined || !value.startsWith(prefix))
53
107
  return undefined;
54
108
  try {
55
- const encoded = value.slice(VERIFIED_WRITER_PREFIX.length);
109
+ const encoded = value.slice(prefix.length);
56
110
  const decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
57
111
  const identity = effect_1.Schema.decodeUnknownSync(VerifiedWriterIdentitySchema)(decoded);
58
112
  if (identity.machineId.length === 0
@@ -68,18 +122,19 @@ function decodeVerified(value) {
68
122
  return undefined;
69
123
  }
70
124
  }
71
- /** Creates recoverable evidence when Linux exposes a stable machine/process identity. */
125
+ /** Seals recoverable evidence only when every platform identity can be observed. */
72
126
  function createRunWriterGeneration(generation) {
73
- if (process.platform !== "linux")
127
+ if (verifiedPrefix() === undefined)
74
128
  return `${OPAQUE_WRITER_PREFIX}${generation}`;
75
129
  try {
76
- const processStart = linuxProcessStart(process.pid);
130
+ const darwin = process.platform === "darwin";
131
+ const processStart = darwin ? darwinProcessStart(process.pid) : linuxProcessStart(process.pid);
77
132
  if (processStart === undefined)
78
133
  return `${OPAQUE_WRITER_PREFIX}${generation}`;
79
134
  return encodeVerified({
80
- machineId: nonEmptyFile("/etc/machine-id"),
81
- bootId: nonEmptyFile("/proc/sys/kernel/random/boot_id"),
82
- pidNamespace: (0, node_fs_1.readlinkSync)("/proc/self/ns/pid"),
135
+ machineId: darwin ? darwinMachineId() : nonEmptyFile("/etc/machine-id"),
136
+ bootId: darwin ? darwinBootId() : nonEmptyFile("/proc/sys/kernel/random/boot_id"),
137
+ pidNamespace: darwin ? DARWIN_PROCESS_DOMAIN : (0, node_fs_1.readlinkSync)("/proc/self/ns/pid"),
83
138
  pid: process.pid,
84
139
  processStart,
85
140
  generation,
@@ -92,21 +147,28 @@ function createRunWriterGeneration(generation) {
92
147
  /** Verifies termination without treating age, permission failures, or a foreign host as evidence. */
93
148
  function observeRunWriterTermination(writerGeneration) {
94
149
  const identity = decodeVerified(writerGeneration);
95
- if (identity === undefined || process.platform !== "linux")
150
+ if (identity === undefined)
96
151
  return { state: "unproven" };
97
152
  try {
98
- if (nonEmptyFile("/etc/machine-id") !== identity.machineId)
153
+ const darwin = process.platform === "darwin";
154
+ const machineId = darwin ? darwinMachineId() : nonEmptyFile("/etc/machine-id");
155
+ if (machineId !== identity.machineId)
99
156
  return { state: "unproven" };
100
- if ((0, node_fs_1.readlinkSync)("/proc/self/ns/pid") !== identity.pidNamespace)
157
+ const pidNamespace = darwin ? DARWIN_PROCESS_DOMAIN : (0, node_fs_1.readlinkSync)("/proc/self/ns/pid");
158
+ if (pidNamespace !== identity.pidNamespace)
101
159
  return { state: "unproven" };
102
- const currentBootId = nonEmptyFile("/proc/sys/kernel/random/boot_id");
160
+ const currentBootId = darwin ? darwinBootId() : nonEmptyFile("/proc/sys/kernel/random/boot_id");
161
+ const terminated = () => ({
162
+ state: "terminated", evidenceIdentity: writerGeneration,
163
+ evidenceKind: darwin ? "local-darwin-process-terminated-v1" : "local-linux-process-terminated-v1",
164
+ });
103
165
  if (currentBootId !== identity.bootId) {
104
- return { state: "terminated", evidenceIdentity: writerGeneration };
166
+ return terminated();
105
167
  }
106
- const currentProcessStart = linuxProcessStart(identity.pid);
168
+ const currentProcessStart = darwin ? darwinProcessStart(identity.pid) : linuxProcessStart(identity.pid);
107
169
  if (currentProcessStart === identity.processStart)
108
170
  return { state: "active" };
109
- return { state: "terminated", evidenceIdentity: writerGeneration };
171
+ return terminated();
110
172
  }
111
173
  catch {
112
174
  return { state: "unproven" };
@@ -1 +1 @@
1
- {"version":3,"file":"owner-identity.js","sourceRoot":"","sources":["owner-identity.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, readlinkSync } from \"node:fs\";\nimport { Schema } from \"effect\";\nconst VERIFIED_WRITER_PREFIX = \"local-linux-process-v1:\";\nconst OPAQUE_WRITER_PREFIX = \"opaque-writer-v1:\";\nconst VerifiedWriterIdentitySchema = Schema.Struct({\n machineId: Schema.String,\n bootId: Schema.String,\n pidNamespace: Schema.String,\n pid: Schema.Int,\n processStart: Schema.String,\n generation: Schema.String,\n});\nexport interface VerifiedWriterIdentity extends Schema.Schema.Type<typeof VerifiedWriterIdentitySchema> {\n}\nexport type WriterTerminationObservation = {\n readonly state: \"terminated\";\n readonly evidenceIdentity: string;\n} | {\n readonly state: \"active\";\n} | {\n readonly state: \"unproven\";\n};\nfunction nonEmptyFile(path: string): string {\n const value = readFileSync(path, \"utf8\").trim();\n if (value.length === 0)\n throw new Error(`${path} did not contain an identity`);\n return value;\n}\nfunction linuxProcessStart(pid: number): string | undefined {\n let raw: string;\n try {\n raw = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n }\n catch (cause) {\n if ((cause as NodeJS.ErrnoException).code === \"ENOENT\")\n return undefined;\n throw cause;\n }\n const closing = raw.lastIndexOf(\")\");\n if (closing < 0 || raw[closing + 1] !== \" \")\n throw new Error(\"Linux process identity is malformed\");\n const fields = raw.slice(closing + 2).trim().split(/\\s+/u);\n const state = fields[0];\n if (state === \"Z\" || state === \"X\" || state === \"x\")\n return undefined;\n if (state === undefined || !/^[A-Za-z]$/u.test(state))\n throw new Error(\"Linux process state is malformed\");\n const processStart = fields[19];\n if (processStart === undefined || !/^\\d+$/u.test(processStart)) {\n throw new Error(\"Linux process start identity is malformed\");\n }\n return processStart;\n}\nfunction encodeVerified(identity: VerifiedWriterIdentity): string {\n return `${VERIFIED_WRITER_PREFIX}${Buffer.from(JSON.stringify(identity), \"utf8\").toString(\"base64url\")}`;\n}\nfunction decodeVerified(value: string): VerifiedWriterIdentity | undefined {\n if (!value.startsWith(VERIFIED_WRITER_PREFIX))\n return undefined;\n try {\n const encoded = value.slice(VERIFIED_WRITER_PREFIX.length);\n const decoded: unknown = JSON.parse(Buffer.from(encoded, \"base64url\").toString(\"utf8\"));\n const identity = Schema.decodeUnknownSync(VerifiedWriterIdentitySchema)(decoded);\n if (identity.machineId.length === 0\n || identity.bootId.length === 0\n || identity.pidNamespace.length === 0\n || identity.pid < 1\n || identity.processStart.length === 0\n || identity.generation.length === 0)\n return undefined;\n return identity;\n }\n catch {\n return undefined;\n }\n}\n/** Creates recoverable evidence when Linux exposes a stable machine/process identity. */\nexport function createRunWriterGeneration(generation: string): string {\n if (process.platform !== \"linux\")\n return `${OPAQUE_WRITER_PREFIX}${generation}`;\n try {\n const processStart = linuxProcessStart(process.pid);\n if (processStart === undefined)\n return `${OPAQUE_WRITER_PREFIX}${generation}`;\n return encodeVerified({\n machineId: nonEmptyFile(\"/etc/machine-id\"),\n bootId: nonEmptyFile(\"/proc/sys/kernel/random/boot_id\"),\n pidNamespace: readlinkSync(\"/proc/self/ns/pid\"),\n pid: process.pid,\n processStart,\n generation,\n });\n }\n catch {\n return `${OPAQUE_WRITER_PREFIX}${generation}`;\n }\n}\n/** Verifies termination without treating age, permission failures, or a foreign host as evidence. */\nexport function observeRunWriterTermination(writerGeneration: string): WriterTerminationObservation {\n const identity = decodeVerified(writerGeneration);\n if (identity === undefined || process.platform !== \"linux\")\n return { state: \"unproven\" };\n try {\n if (nonEmptyFile(\"/etc/machine-id\") !== identity.machineId)\n return { state: \"unproven\" };\n if (readlinkSync(\"/proc/self/ns/pid\") !== identity.pidNamespace)\n return { state: \"unproven\" };\n const currentBootId = nonEmptyFile(\"/proc/sys/kernel/random/boot_id\");\n if (currentBootId !== identity.bootId) {\n return { state: \"terminated\", evidenceIdentity: writerGeneration };\n }\n const currentProcessStart = linuxProcessStart(identity.pid);\n if (currentProcessStart === identity.processStart)\n return { state: \"active\" };\n return { state: \"terminated\", evidenceIdentity: writerGeneration };\n }\n catch {\n return { state: \"unproven\" };\n }\n}\n"]}
1
+ {"version":3,"file":"owner-identity.js","sourceRoot":"","sources":["owner-identity.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, readlinkSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport { Schema } from \"effect\";\nconst VERIFIED_WRITER_PREFIX = \"local-linux-process-v1:\";\nconst DARWIN_WRITER_PREFIX = \"local-darwin-process-v1:\";\nconst OPAQUE_WRITER_PREFIX = \"opaque-writer-v1:\";\nconst DARWIN_PROCESS_DOMAIN = \"darwin-host\";\nconst VerifiedWriterIdentitySchema = Schema.Struct({\n machineId: Schema.String,\n bootId: Schema.String,\n pidNamespace: Schema.String,\n pid: Schema.Int,\n processStart: Schema.String,\n generation: Schema.String,\n});\nexport interface VerifiedWriterIdentity extends Schema.Schema.Type<typeof VerifiedWriterIdentitySchema> {\n}\nexport type WriterTerminationObservation = {\n readonly state: \"terminated\";\n readonly evidenceIdentity: string;\n readonly evidenceKind: string;\n} | {\n readonly state: \"active\";\n} | {\n readonly state: \"unproven\";\n};\nfunction nonEmptyFile(path: string): string {\n const value = readFileSync(path, \"utf8\").trim();\n if (value.length === 0)\n throw new Error(`${path} did not contain an identity`);\n return value;\n}\nfunction linuxProcessStart(pid: number): string | undefined {\n let raw: string;\n try {\n raw = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n }\n catch (cause) {\n if ((cause as NodeJS.ErrnoException).code === \"ENOENT\")\n return undefined;\n throw cause;\n }\n const closing = raw.lastIndexOf(\")\");\n if (closing < 0 || raw[closing + 1] !== \" \")\n throw new Error(\"Linux process identity is malformed\");\n const fields = raw.slice(closing + 2).trim().split(/\\s+/u);\n const state = fields[0];\n if (state === \"Z\" || state === \"X\" || state === \"x\")\n return undefined;\n if (state === undefined || !/^[A-Za-z]$/u.test(state))\n throw new Error(\"Linux process state is malformed\");\n const processStart = fields[19];\n if (processStart === undefined || !/^\\d+$/u.test(processStart)) {\n throw new Error(\"Linux process start identity is malformed\");\n }\n return processStart;\n}\nfunction darwinCommand(command: string, args: readonly string[]): string {\n return execFileSync(command, args, {\n encoding: \"utf8\",\n env: { ...process.env, LC_ALL: \"C\", TZ: \"UTC\" },\n timeout: 5000,\n maxBuffer: 1024 * 1024,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n }).trim();\n}\nfunction darwinUuid(value: string): string {\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(value)) {\n throw new Error(\"Darwin system identity is malformed\");\n }\n return value.toLowerCase();\n}\nfunction darwinMachineId(): string {\n const platform = darwinCommand(\"/usr/sbin/ioreg\", [\"-rd1\", \"-c\", \"IOPlatformExpertDevice\"]);\n const matches = [...platform.matchAll(/\"IOPlatformUUID\"\\s*=\\s*\"([^\"]+)\"/gu)];\n if (matches.length !== 1)\n throw new Error(\"Darwin platform identity is unavailable\");\n return darwinUuid(matches[0]![1]!);\n}\nfunction darwinBootId(): string {\n return darwinUuid(darwinCommand(\"/usr/sbin/sysctl\", [\"-n\", \"kern.bootsessionuuid\"]));\n}\n/** ps lstart reads the kernel process start time, rendered to seconds in a fixed locale/zone. */\nfunction darwinProcessStart(pid: number): string | undefined {\n let value: string;\n try {\n value = darwinCommand(\"/bin/ps\", [\"-p\", String(pid), \"-o\", \"lstart=\"]);\n }\n catch (cause) {\n const failure = cause as {\n status?: number;\n signal?: string | null;\n stdout?: string;\n stderr?: string;\n };\n // ps exits 1 without diagnostics when the requested pid does not exist.\n // Permission, launch, timeout, signal and parse failures cannot prove termination.\n if (failure.status === 1 && failure.signal == null && failure.stdout === \"\" && failure.stderr === \"\") {\n return undefined;\n }\n throw cause;\n }\n if (!/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4}$/u.test(value) ||\n !Number.isFinite(Date.parse(`${value} UTC`))) {\n throw new Error(\"Darwin process start identity is malformed\");\n }\n return value;\n}\nfunction verifiedPrefix(): string | undefined {\n return process.platform === \"linux\" ? VERIFIED_WRITER_PREFIX\n : process.platform === \"darwin\" ? DARWIN_WRITER_PREFIX : undefined;\n}\nfunction encodeVerified(identity: VerifiedWriterIdentity): string {\n return `${verifiedPrefix()}${Buffer.from(JSON.stringify(identity), \"utf8\").toString(\"base64url\")}`;\n}\nfunction decodeVerified(value: string): VerifiedWriterIdentity | undefined {\n const prefix = verifiedPrefix();\n if (prefix === undefined || !value.startsWith(prefix))\n return undefined;\n try {\n const encoded = value.slice(prefix.length);\n const decoded: unknown = JSON.parse(Buffer.from(encoded, \"base64url\").toString(\"utf8\"));\n const identity = Schema.decodeUnknownSync(VerifiedWriterIdentitySchema)(decoded);\n if (identity.machineId.length === 0\n || identity.bootId.length === 0\n || identity.pidNamespace.length === 0\n || identity.pid < 1\n || identity.processStart.length === 0\n || identity.generation.length === 0)\n return undefined;\n return identity;\n }\n catch {\n return undefined;\n }\n}\n/** Seals recoverable evidence only when every platform identity can be observed. */\nexport function createRunWriterGeneration(generation: string): string {\n if (verifiedPrefix() === undefined)\n return `${OPAQUE_WRITER_PREFIX}${generation}`;\n try {\n const darwin = process.platform === \"darwin\";\n const processStart = darwin ? darwinProcessStart(process.pid) : linuxProcessStart(process.pid);\n if (processStart === undefined)\n return `${OPAQUE_WRITER_PREFIX}${generation}`;\n return encodeVerified({\n machineId: darwin ? darwinMachineId() : nonEmptyFile(\"/etc/machine-id\"),\n bootId: darwin ? darwinBootId() : nonEmptyFile(\"/proc/sys/kernel/random/boot_id\"),\n pidNamespace: darwin ? DARWIN_PROCESS_DOMAIN : readlinkSync(\"/proc/self/ns/pid\"),\n pid: process.pid,\n processStart,\n generation,\n });\n }\n catch {\n return `${OPAQUE_WRITER_PREFIX}${generation}`;\n }\n}\n/** Verifies termination without treating age, permission failures, or a foreign host as evidence. */\nexport function observeRunWriterTermination(writerGeneration: string): WriterTerminationObservation {\n const identity = decodeVerified(writerGeneration);\n if (identity === undefined)\n return { state: \"unproven\" };\n try {\n const darwin = process.platform === \"darwin\";\n const machineId = darwin ? darwinMachineId() : nonEmptyFile(\"/etc/machine-id\");\n if (machineId !== identity.machineId)\n return { state: \"unproven\" };\n const pidNamespace = darwin ? DARWIN_PROCESS_DOMAIN : readlinkSync(\"/proc/self/ns/pid\");\n if (pidNamespace !== identity.pidNamespace)\n return { state: \"unproven\" };\n const currentBootId = darwin ? darwinBootId() : nonEmptyFile(\"/proc/sys/kernel/random/boot_id\");\n const terminated = (): WriterTerminationObservation => ({\n state: \"terminated\", evidenceIdentity: writerGeneration,\n evidenceKind: darwin ? \"local-darwin-process-terminated-v1\" : \"local-linux-process-terminated-v1\",\n });\n if (currentBootId !== identity.bootId) {\n return terminated();\n }\n const currentProcessStart = darwin ? darwinProcessStart(identity.pid) : linuxProcessStart(identity.pid);\n if (currentProcessStart === identity.processStart)\n return { state: \"active\" };\n return terminated();\n }\n catch {\n return { state: \"unproven\" };\n }\n}\n"]}
@@ -12,12 +12,13 @@ export interface VerifiedWriterIdentity extends Schema.Schema.Type<typeof Verifi
12
12
  export type WriterTerminationObservation = {
13
13
  readonly state: "terminated";
14
14
  readonly evidenceIdentity: string;
15
+ readonly evidenceKind: string;
15
16
  } | {
16
17
  readonly state: "active";
17
18
  } | {
18
19
  readonly state: "unproven";
19
20
  };
20
- /** Creates recoverable evidence when Linux exposes a stable machine/process identity. */
21
+ /** Seals recoverable evidence only when every platform identity can be observed. */
21
22
  export declare function createRunWriterGeneration(generation: string): string;
22
23
  /** Verifies termination without treating age, permission failures, or a foreign host as evidence. */
23
24
  export declare function observeRunWriterTermination(writerGeneration: string): WriterTerminationObservation;
@@ -12,12 +12,13 @@ export interface VerifiedWriterIdentity extends Schema.Schema.Type<typeof Verifi
12
12
  export type WriterTerminationObservation = {
13
13
  readonly state: "terminated";
14
14
  readonly evidenceIdentity: string;
15
+ readonly evidenceKind: string;
15
16
  } | {
16
17
  readonly state: "active";
17
18
  } | {
18
19
  readonly state: "unproven";
19
20
  };
20
- /** Creates recoverable evidence when Linux exposes a stable machine/process identity. */
21
+ /** Seals recoverable evidence only when every platform identity can be observed. */
21
22
  export declare function createRunWriterGeneration(generation: string): string;
22
23
  /** Verifies termination without treating age, permission failures, or a foreign host as evidence. */
23
24
  export declare function observeRunWriterTermination(writerGeneration: string): WriterTerminationObservation;
@@ -12,12 +12,13 @@ export interface VerifiedWriterIdentity extends Schema.Schema.Type<typeof Verifi
12
12
  export type WriterTerminationObservation = {
13
13
  readonly state: "terminated";
14
14
  readonly evidenceIdentity: string;
15
+ readonly evidenceKind: string;
15
16
  } | {
16
17
  readonly state: "active";
17
18
  } | {
18
19
  readonly state: "unproven";
19
20
  };
20
- /** Creates recoverable evidence when Linux exposes a stable machine/process identity. */
21
+ /** Seals recoverable evidence only when every platform identity can be observed. */
21
22
  export declare function createRunWriterGeneration(generation: string): string;
22
23
  /** Verifies termination without treating age, permission failures, or a foreign host as evidence. */
23
24
  export declare function observeRunWriterTermination(writerGeneration: string): WriterTerminationObservation;