@b00dea/cockpit 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/LICENSE +21 -0
  3. package/README.md +22 -2
  4. package/bin/cockpit.mjs +33 -0
  5. package/cockpit.schema.json +2574 -0
  6. package/dist/autonomy.d.ts +44 -0
  7. package/dist/autonomy.js +156 -0
  8. package/dist/bounded-read.d.ts +14 -0
  9. package/dist/bounded-read.js +42 -0
  10. package/dist/browser/commands.d.ts +62 -0
  11. package/dist/browser/commands.js +349 -0
  12. package/dist/browser/package-paths.d.ts +1 -0
  13. package/dist/browser/package-paths.js +6 -0
  14. package/dist/browser/proxy.d.ts +22 -0
  15. package/dist/browser/proxy.js +37 -0
  16. package/dist/browser/runtime.d.ts +117 -0
  17. package/dist/browser/runtime.js +183 -0
  18. package/dist/browser/surfaces.d.ts +141 -0
  19. package/dist/browser/surfaces.js +556 -0
  20. package/dist/browser/ui-gate.d.ts +15 -0
  21. package/dist/browser/ui-gate.js +18 -0
  22. package/dist/cli-guard.d.ts +5 -0
  23. package/dist/cli-guard.js +71 -0
  24. package/dist/cli-main.d.ts +139 -0
  25. package/dist/cli-main.js +1405 -0
  26. package/dist/cli.d.ts +3 -0
  27. package/dist/cli.js +16 -0
  28. package/dist/command-table.d.ts +113 -0
  29. package/dist/command-table.js +512 -0
  30. package/dist/config/load.d.ts +171 -0
  31. package/dist/config/load.js +345 -0
  32. package/dist/config/sibling-toml.d.ts +48 -0
  33. package/dist/config/sibling-toml.js +160 -0
  34. package/dist/config/surface-tools-toml.d.ts +9 -0
  35. package/dist/config/surface-tools-toml.js +37 -0
  36. package/dist/config/verified-write.d.ts +43 -0
  37. package/dist/config/verified-write.js +89 -0
  38. package/dist/diagnostics.d.ts +26 -0
  39. package/dist/diagnostics.js +335 -0
  40. package/dist/emit.d.ts +22 -0
  41. package/dist/emit.js +43 -0
  42. package/dist/entrypoint-kinds.d.ts +3 -0
  43. package/dist/entrypoint-kinds.js +11 -0
  44. package/dist/environment/application/destructive.d.ts +6 -0
  45. package/dist/environment/application/destructive.js +425 -0
  46. package/dist/environment/application/doctor.d.ts +89 -0
  47. package/dist/environment/application/doctor.js +235 -0
  48. package/dist/environment/application/guard.d.ts +43 -0
  49. package/dist/environment/application/guard.js +622 -0
  50. package/dist/environment/application/health.d.ts +134 -0
  51. package/dist/environment/application/health.js +379 -0
  52. package/dist/environment/application/lifecycle-context.d.ts +228 -0
  53. package/dist/environment/application/lifecycle-context.js +154 -0
  54. package/dist/environment/application/lifecycle-state.d.ts +25 -0
  55. package/dist/environment/application/lifecycle-state.js +201 -0
  56. package/dist/environment/application/lifecycle.d.ts +17 -0
  57. package/dist/environment/application/lifecycle.js +729 -0
  58. package/dist/environment/application/logs.d.ts +45 -0
  59. package/dist/environment/application/logs.js +127 -0
  60. package/dist/environment/application/setup.d.ts +129 -0
  61. package/dist/environment/application/setup.js +741 -0
  62. package/dist/environment/application/shared.d.ts +11 -0
  63. package/dist/environment/application/shared.js +61 -0
  64. package/dist/environment/claims.d.ts +389 -0
  65. package/dist/environment/claims.js +1709 -0
  66. package/dist/environment/codex-hook-trust.d.ts +11 -0
  67. package/dist/environment/codex-hook-trust.js +185 -0
  68. package/dist/environment/compose-environment.d.ts +1 -0
  69. package/dist/environment/compose-environment.js +6 -0
  70. package/dist/environment/compose-ownership.d.ts +21 -0
  71. package/dist/environment/compose-ownership.js +117 -0
  72. package/dist/environment/compose-topology.d.ts +117 -0
  73. package/dist/environment/compose-topology.js +413 -0
  74. package/dist/environment/contract.d.ts +489 -0
  75. package/dist/environment/contract.js +761 -0
  76. package/dist/environment/declaration.d.ts +14 -0
  77. package/dist/environment/declaration.js +39 -0
  78. package/dist/environment/destructive-composition.d.ts +29 -0
  79. package/dist/environment/destructive-composition.js +333 -0
  80. package/dist/environment/docker-daemon.d.ts +30 -0
  81. package/dist/environment/docker-daemon.js +78 -0
  82. package/dist/environment/docker-endpoint.d.ts +10 -0
  83. package/dist/environment/docker-endpoint.js +19 -0
  84. package/dist/environment/env-schema-observation.d.ts +46 -0
  85. package/dist/environment/env-schema-observation.js +241 -0
  86. package/dist/environment/evidence.d.ts +136 -0
  87. package/dist/environment/evidence.js +437 -0
  88. package/dist/environment/executable.d.ts +26 -0
  89. package/dist/environment/executable.js +167 -0
  90. package/dist/environment/generated-application/authorities.d.ts +5 -0
  91. package/dist/environment/generated-application/authorities.js +61 -0
  92. package/dist/environment/generated-application/bootstrap-skill.d.ts +16 -0
  93. package/dist/environment/generated-application/bootstrap-skill.js +328 -0
  94. package/dist/environment/generated-application/check.d.ts +13 -0
  95. package/dist/environment/generated-application/check.js +189 -0
  96. package/dist/environment/generated-application/custom-surface.d.ts +26 -0
  97. package/dist/environment/generated-application/custom-surface.js +289 -0
  98. package/dist/environment/generated-application/prepare.d.ts +29 -0
  99. package/dist/environment/generated-application/prepare.js +276 -0
  100. package/dist/environment/generated-application/publication.d.ts +33 -0
  101. package/dist/environment/generated-application/publication.js +547 -0
  102. package/dist/environment/generated-application/shared.d.ts +484 -0
  103. package/dist/environment/generated-application/shared.js +349 -0
  104. package/dist/environment/generated-application/surface-observation.d.ts +4 -0
  105. package/dist/environment/generated-application/surface-observation.js +69 -0
  106. package/dist/environment/generated-application/surface-outputs.d.ts +71 -0
  107. package/dist/environment/generated-application/surface-outputs.js +389 -0
  108. package/dist/environment/generated-application/surfaces.d.ts +3 -0
  109. package/dist/environment/generated-application/surfaces.js +699 -0
  110. package/dist/environment/generated-application/sync.d.ts +6 -0
  111. package/dist/environment/generated-application/sync.js +109 -0
  112. package/dist/environment/git-observation.d.ts +183 -0
  113. package/dist/environment/git-observation.js +544 -0
  114. package/dist/environment/health-composition.d.ts +11 -0
  115. package/dist/environment/health-composition.js +628 -0
  116. package/dist/environment/host-observation.d.ts +56 -0
  117. package/dist/environment/host-observation.js +52 -0
  118. package/dist/environment/identity.d.ts +48 -0
  119. package/dist/environment/identity.js +85 -0
  120. package/dist/environment/init-application.d.ts +308 -0
  121. package/dist/environment/init-application.js +697 -0
  122. package/dist/environment/install-policy-observation.d.ts +71 -0
  123. package/dist/environment/install-policy-observation.js +284 -0
  124. package/dist/environment/install-policy.d.ts +48 -0
  125. package/dist/environment/install-policy.js +96 -0
  126. package/dist/environment/instance.d.ts +33 -0
  127. package/dist/environment/instance.js +122 -0
  128. package/dist/environment/instruction-pointer.d.ts +19 -0
  129. package/dist/environment/instruction-pointer.js +144 -0
  130. package/dist/environment/lifecycle-composition.d.ts +29 -0
  131. package/dist/environment/lifecycle-composition.js +675 -0
  132. package/dist/environment/lifecycle-stage.d.ts +115 -0
  133. package/dist/environment/lifecycle-stage.js +398 -0
  134. package/dist/environment/lifecycle.d.ts +75 -0
  135. package/dist/environment/lifecycle.js +354 -0
  136. package/dist/environment/logs.d.ts +132 -0
  137. package/dist/environment/logs.js +519 -0
  138. package/dist/environment/observations.d.ts +46 -0
  139. package/dist/environment/observations.js +344 -0
  140. package/dist/environment/operator-application.d.ts +50 -0
  141. package/dist/environment/operator-application.js +155 -0
  142. package/dist/environment/ports.d.ts +182 -0
  143. package/dist/environment/ports.js +1205 -0
  144. package/dist/environment/posture-observation.d.ts +68 -0
  145. package/dist/environment/posture-observation.js +253 -0
  146. package/dist/environment/read-composition.d.ts +27 -0
  147. package/dist/environment/read-composition.js +352 -0
  148. package/dist/environment/readiness-composition.d.ts +38 -0
  149. package/dist/environment/readiness-composition.js +130 -0
  150. package/dist/environment/reclaim.d.ts +333 -0
  151. package/dist/environment/reclaim.js +1835 -0
  152. package/dist/environment/repository-identity.d.ts +13 -0
  153. package/dist/environment/repository-identity.js +108 -0
  154. package/dist/environment/runtime-measurement-record.d.ts +38 -0
  155. package/dist/environment/runtime-measurement-record.js +111 -0
  156. package/dist/environment/runtime-measurement.d.ts +27 -0
  157. package/dist/environment/runtime-measurement.js +224 -0
  158. package/dist/environment/runtime-probe-residue.d.ts +43 -0
  159. package/dist/environment/runtime-probe-residue.js +148 -0
  160. package/dist/environment/runtime-probe.d.ts +72 -0
  161. package/dist/environment/runtime-probe.js +725 -0
  162. package/dist/environment/runtime.d.ts +505 -0
  163. package/dist/environment/runtime.js +2335 -0
  164. package/dist/environment/seed.d.ts +16 -0
  165. package/dist/environment/seed.js +43 -0
  166. package/dist/environment/selftest-application.d.ts +86 -0
  167. package/dist/environment/selftest-application.js +713 -0
  168. package/dist/environment/sensitive.d.ts +3 -0
  169. package/dist/environment/sensitive.js +48 -0
  170. package/dist/environment/setup-observation.d.ts +62 -0
  171. package/dist/environment/setup-observation.js +1473 -0
  172. package/dist/environment/setup.d.ts +43 -0
  173. package/dist/environment/setup.js +176 -0
  174. package/dist/environment/sibling-instructions.d.ts +33 -0
  175. package/dist/environment/sibling-instructions.js +224 -0
  176. package/dist/environment/sibling-registration.d.ts +45 -0
  177. package/dist/environment/sibling-registration.js +538 -0
  178. package/dist/environment/state.d.ts +371 -0
  179. package/dist/environment/state.js +2013 -0
  180. package/dist/environment/templates.d.ts +140 -0
  181. package/dist/environment/templates.js +685 -0
  182. package/dist/environment/tool-registration.d.ts +9 -0
  183. package/dist/environment/tool-registration.js +96 -0
  184. package/dist/environment/upgrade-application.d.ts +19 -0
  185. package/dist/environment/upgrade-application.js +175 -0
  186. package/dist/environment-exec/execute.d.ts +102 -0
  187. package/dist/environment-exec/execute.js +1175 -0
  188. package/dist/environment-exec/libexec-program.d.ts +6 -0
  189. package/dist/environment-exec/libexec-program.js +22 -0
  190. package/dist/environment-exec/verified-digest.d.ts +4 -0
  191. package/dist/environment-exec/verified-digest.js +16 -0
  192. package/dist/exact-keys.d.ts +7 -0
  193. package/dist/exact-keys.js +15 -0
  194. package/dist/fix-catalogue.d.ts +32 -0
  195. package/dist/fix-catalogue.js +60 -0
  196. package/dist/freshness.d.ts +29 -0
  197. package/dist/freshness.js +75 -0
  198. package/dist/generated-environment/adopt.d.ts +16 -0
  199. package/dist/generated-environment/adopt.js +275 -0
  200. package/dist/generated-environment/command.d.ts +47 -0
  201. package/dist/generated-environment/command.js +75 -0
  202. package/dist/generated-environment/transaction.d.ts +186 -0
  203. package/dist/generated-environment/transaction.js +1770 -0
  204. package/dist/grading/evaluate.d.ts +71 -0
  205. package/dist/grading/evaluate.js +403 -0
  206. package/dist/grading/grade.d.ts +33 -0
  207. package/dist/grading/grade.js +57 -0
  208. package/dist/guards/evaluator.d.ts +113 -0
  209. package/dist/guards/evaluator.js +1226 -0
  210. package/dist/guards/harness-adapter.d.ts +17 -0
  211. package/dist/guards/harness-adapter.js +57 -0
  212. package/dist/guards/host.d.ts +8 -0
  213. package/dist/guards/host.js +10 -0
  214. package/dist/guards/invocation-parser.d.ts +66 -0
  215. package/dist/guards/invocation-parser.js +595 -0
  216. package/dist/guards/local-identity.d.ts +40 -0
  217. package/dist/guards/local-identity.js +123 -0
  218. package/dist/guards/policy-pin.d.ts +13 -0
  219. package/dist/guards/policy-pin.js +175 -0
  220. package/dist/guards/protected-locations.d.ts +62 -0
  221. package/dist/guards/protected-locations.js +461 -0
  222. package/dist/guards/read-only.d.ts +37 -0
  223. package/dist/guards/read-only.js +315 -0
  224. package/dist/init/command.d.ts +40 -0
  225. package/dist/init/command.js +310 -0
  226. package/dist/init/derive.d.ts +51 -0
  227. package/dist/init/derive.js +715 -0
  228. package/dist/init/draft.d.ts +138 -0
  229. package/dist/init/draft.js +1205 -0
  230. package/dist/init/render.d.ts +35 -0
  231. package/dist/init/render.js +82 -0
  232. package/dist/init/scaffold.d.ts +53 -0
  233. package/dist/init/scaffold.js +121 -0
  234. package/dist/invocation.d.ts +13 -0
  235. package/dist/invocation.js +20 -0
  236. package/dist/package-metadata.d.ts +9 -0
  237. package/dist/package-metadata.js +19 -0
  238. package/dist/readiness.d.ts +53 -0
  239. package/dist/readiness.js +88 -0
  240. package/dist/references/named.d.ts +24 -0
  241. package/dist/references/named.js +27 -0
  242. package/dist/refusal.d.ts +15 -0
  243. package/dist/refusal.js +7 -0
  244. package/dist/registry-derivation.d.ts +31 -0
  245. package/dist/registry-derivation.js +32 -0
  246. package/dist/registry-resolve/command.d.ts +47 -0
  247. package/dist/registry-resolve/command.js +226 -0
  248. package/dist/registry-resolve/registry.d.ts +68 -0
  249. package/dist/registry-resolve/registry.js +292 -0
  250. package/dist/registry-resolve/render-shell.d.ts +18 -0
  251. package/dist/registry-resolve/render-shell.js +36 -0
  252. package/dist/repair.d.ts +29 -0
  253. package/dist/repair.js +8 -0
  254. package/dist/schema-json.d.ts +1 -0
  255. package/dist/schema-json.js +177 -0
  256. package/dist/schema.d.ts +1322 -0
  257. package/dist/schema.js +934 -0
  258. package/dist/setup/command.d.ts +4 -0
  259. package/dist/setup/command.js +4 -0
  260. package/dist/sha256.d.ts +1 -0
  261. package/dist/sha256.js +4 -0
  262. package/dist/surfaces/adoption.d.ts +41 -0
  263. package/dist/surfaces/adoption.js +217 -0
  264. package/dist/surfaces/consumer-instructions.d.ts +20 -0
  265. package/dist/surfaces/consumer-instructions.js +43 -0
  266. package/dist/surfaces/contract.d.ts +42 -0
  267. package/dist/surfaces/contract.js +169 -0
  268. package/dist/surfaces/core-declarations.d.ts +24 -0
  269. package/dist/surfaces/core-declarations.js +79 -0
  270. package/dist/surfaces/development-markers.d.ts +1 -0
  271. package/dist/surfaces/development-markers.js +18 -0
  272. package/dist/surfaces/generator-adapter.d.ts +71 -0
  273. package/dist/surfaces/generator-adapter.js +809 -0
  274. package/dist/surfaces/harness-registry.d.ts +180 -0
  275. package/dist/surfaces/harness-registry.js +117 -0
  276. package/dist/surfaces/mcp.d.ts +95 -0
  277. package/dist/surfaces/mcp.js +186 -0
  278. package/dist/surfaces/merge.d.ts +30 -0
  279. package/dist/surfaces/merge.js +105 -0
  280. package/dist/surfaces/ownership.d.ts +190 -0
  281. package/dist/surfaces/ownership.js +795 -0
  282. package/dist/surfaces/projection.d.ts +136 -0
  283. package/dist/surfaces/projection.js +681 -0
  284. package/dist/surfaces/render.d.ts +118 -0
  285. package/dist/surfaces/render.js +633 -0
  286. package/dist/surfaces/restrictions.d.ts +130 -0
  287. package/dist/surfaces/restrictions.js +447 -0
  288. package/dist/surfaces/selftest.d.ts +162 -0
  289. package/dist/surfaces/selftest.js +393 -0
  290. package/dist/surfaces/skill-contract.d.ts +85 -0
  291. package/dist/surfaces/skill-contract.js +449 -0
  292. package/dist/surfaces/sync.d.ts +57 -0
  293. package/dist/surfaces/sync.js +164 -0
  294. package/dist/team-metadata.d.ts +41 -0
  295. package/dist/team-metadata.js +512 -0
  296. package/dist/testing/gates.d.ts +91 -0
  297. package/dist/testing/gates.js +182 -0
  298. package/dist/testing/hooks.d.ts +59 -0
  299. package/dist/testing/hooks.js +139 -0
  300. package/dist/testing/verdict.d.ts +29 -0
  301. package/dist/testing/verdict.js +62 -0
  302. package/dist/work-orders/application.d.ts +99 -0
  303. package/dist/work-orders/application.js +383 -0
  304. package/dist/work-orders/composition.d.ts +124 -0
  305. package/dist/work-orders/composition.js +1010 -0
  306. package/dist/work-orders/contract.d.ts +61 -0
  307. package/dist/work-orders/contract.js +122 -0
  308. package/dist/work-orders/store.d.ts +158 -0
  309. package/dist/work-orders/store.js +197 -0
  310. package/docs/README.md +65 -0
  311. package/docs/architecture.md +136 -0
  312. package/docs/capability-matrix.md +50 -0
  313. package/docs/cli-reference.md +599 -0
  314. package/docs/command-list.md +51 -0
  315. package/docs/compose-patterns.md +99 -0
  316. package/docs/concepts.md +171 -0
  317. package/docs/configuration-essentials.md +172 -0
  318. package/docs/configuration-reference.md +621 -0
  319. package/docs/environment.md +760 -0
  320. package/docs/extending.md +43 -0
  321. package/docs/faq.md +111 -0
  322. package/docs/getting-started.md +608 -0
  323. package/docs/harness-surfaces.md +433 -0
  324. package/docs/joining-a-team.md +76 -0
  325. package/docs/release-policy.md +49 -0
  326. package/docs/safety-and-autonomy.md +419 -0
  327. package/docs/troubleshooting.md +361 -0
  328. package/docs/tutorial.md +170 -0
  329. package/docs/work-and-browser.md +254 -0
  330. package/libexec/browser-operation.cjs +186 -0
  331. package/libexec/fence-marker.cjs +101 -0
  332. package/libexec/fence-marker.d.cts +24 -0
  333. package/libexec/fenced-group-runner.cjs +77 -0
  334. package/libexec/fenced-supervisor.cjs +137 -0
  335. package/libexec/generated-filesystem.cjs +731 -0
  336. package/libexec/install-filesystem.cjs +225 -0
  337. package/libexec/rulesync-generator.NOTICE.md +1112 -0
  338. package/libexec/rulesync-generator.cjs +743 -0
  339. package/libexec/surface-generator-worker.cjs +266 -0
  340. package/libexec/surface-output-reader.cjs +99 -0
  341. package/libexec/surface-scratch-cleanup.cjs +14 -0
  342. package/libexec/validate-harness-evidence.d.mts +183 -0
  343. package/libexec/validate-harness-evidence.mjs +1312 -0
  344. package/package.json +74 -4
  345. package/surfaces/README.md +33 -0
  346. package/surfaces/agents/evaluator.agent.md +76 -0
  347. package/surfaces/guards/bash-guard.sh +48 -0
  348. package/surfaces/guards/claude.adapter.json +25 -0
  349. package/surfaces/guards/codex.adapter.json +24 -0
  350. package/surfaces/guards/opencode.adapter.json +25 -0
  351. package/surfaces/references/browser.md +63 -0
  352. package/surfaces/references/test-data-and-personas.md +84 -0
  353. package/surfaces/references/testing-tiers.md +11 -0
  354. package/surfaces/skills/cockpit-browser.skill.md +54 -0
  355. package/surfaces/skills/cockpit-explain.skill.md +32 -0
  356. package/surfaces/skills/cockpit-fix.skill.md +37 -0
  357. package/surfaces/skills/cockpit-setup.skill.md +39 -0
  358. package/surfaces/skills/cockpit-work.skill.md +34 -0
  359. package/surfaces/skills/collection.json +5 -0
  360. package/surfaces/skills/procedures/explain.md +61 -0
  361. package/surfaces/skills/procedures/fix.md +81 -0
  362. package/surfaces/skills/procedures/setup.md +379 -0
  363. package/surfaces/skills/procedures/work.md +105 -0
@@ -0,0 +1,115 @@
1
+ import { type CheckoutId, type CockpitId, type EnvironmentDiagnostic, type EnvironmentObservation, type HolderId, type LifecycleProgress, type ObservationLifecycleStage, type StackId } from './contract.js';
2
+ import { type StateNamespace, type StateRecord } from './state.js';
3
+ export declare const observationDeclarations: readonly [{
4
+ readonly id: 'state-seed';
5
+ readonly owner: "lifecycle-stage";
6
+ readonly postures: readonly ["environment"];
7
+ readonly stages: readonly [{
8
+ readonly stage: 'bootstrap';
9
+ readonly disposition: 'not-applicable';
10
+ readonly reason: 'the first seed has not completed';
11
+ }, {
12
+ readonly stage: 'steady';
13
+ readonly disposition: 'required';
14
+ }];
15
+ readonly code: "STATE_UNSEEDED";
16
+ readonly isIssued: typeof isLifecycleStageObservation;
17
+ readonly issuedAt: typeof observationIssuedAt;
18
+ }];
19
+ export interface LifecycleRecordValue extends LifecycleProgress {
20
+ readonly holderId: HolderId;
21
+ readonly teardownComplete?: true;
22
+ /**
23
+ * The digest of each file the running stack was started from, by the name a person edits, so a
24
+ * refused declaration change can say which one changed.
25
+ */
26
+ readonly runtimeInputs?: RuntimeInputs;
27
+ }
28
+ export type RuntimeInputs = Readonly<Record<string, string>>;
29
+ export interface CurrentLifecycleRecord {
30
+ readonly record: StateRecord;
31
+ readonly value: LifecycleRecordValue;
32
+ }
33
+ export type EarlierNameResult = Readonly<{
34
+ kind: 'complete';
35
+ name: string | undefined;
36
+ }> | Readonly<{
37
+ kind: 'refusal';
38
+ code: EnvironmentDiagnostic['code'];
39
+ message: string;
40
+ target: string;
41
+ }>;
42
+ export declare function findStackUnderEarlierName(input: Readonly<{
43
+ namespace: StateNamespace;
44
+ cockpitId: CockpitId;
45
+ checkoutId: CheckoutId;
46
+ }>): Promise<EarlierNameResult>;
47
+ export declare function earlierNameRefusalMessage(configPath: string, earlierName: string): string;
48
+ export declare function decodeLifecycleRecord(record: StateRecord, context: Readonly<{
49
+ cockpitId: CockpitId;
50
+ stackId: StackId;
51
+ }>): CurrentLifecycleRecord | undefined;
52
+ export interface LifecycleStageAuthority {
53
+ readonly stackId: StackId;
54
+ readonly stage: ObservationLifecycleStage;
55
+ readonly observedAt: string;
56
+ readonly validThrough: string;
57
+ }
58
+ declare const lifecycleStageProjectionBrand: unique symbol;
59
+ export interface LifecycleStageProjection {
60
+ readonly [lifecycleStageProjectionBrand]: true;
61
+ }
62
+ export interface LifecycleStageEvidence {
63
+ readonly stackId: StackId;
64
+ readonly stage: ObservationLifecycleStage;
65
+ }
66
+ export type LifecycleStageResolution = {
67
+ readonly kind: 'complete';
68
+ readonly authority: LifecycleStageAuthority;
69
+ readonly observation: EnvironmentObservation;
70
+ } | {
71
+ readonly kind: 'refusal';
72
+ readonly diagnostics: readonly EnvironmentDiagnostic[];
73
+ };
74
+ export type LifecycleHistoryTransition = {
75
+ readonly kind: 'complete' | 'unchanged';
76
+ readonly record: StateRecord;
77
+ } | {
78
+ readonly kind: 'refusal';
79
+ readonly diagnostics: readonly EnvironmentDiagnostic[];
80
+ };
81
+ declare function isLifecycleStageObservation(value: unknown): value is EnvironmentObservation;
82
+ declare function observationIssuedAt(value: unknown): number | undefined;
83
+ export declare function resolveLifecycleStage(input: {
84
+ readonly namespace: StateNamespace;
85
+ readonly stackId: StackId;
86
+ readonly observedAt: string;
87
+ }): Promise<LifecycleStageResolution>;
88
+ export declare function observeStateSeed(input: {
89
+ readonly namespace: StateNamespace;
90
+ readonly stackId: StackId;
91
+ readonly observedAt: string;
92
+ }): Promise<EnvironmentObservation>;
93
+ export declare function authenticateLifecycleStageAuthority(value: unknown, stackId: StackId, cockpitId: string, earliest: number, latest: number, evaluatedAt: number): ObservationLifecycleStage | undefined;
94
+ export declare function projectLifecycleStage(input: {
95
+ readonly authority: LifecycleStageAuthority;
96
+ readonly stackId: StackId;
97
+ readonly cockpitId: CockpitId;
98
+ readonly earliest: number;
99
+ readonly latest: number;
100
+ readonly evaluatedAt: number;
101
+ }): LifecycleStageProjection | undefined;
102
+ export declare function consumeLifecycleStageProjection(projection: LifecycleStageProjection): LifecycleStageEvidence | undefined;
103
+ export declare function recordLifecycleStarted(input: {
104
+ readonly namespace: StateNamespace;
105
+ readonly stackId: StackId;
106
+ readonly holderId: HolderId;
107
+ readonly observedAt: string;
108
+ }): Promise<LifecycleHistoryTransition>;
109
+ export declare function recordLifecycleSeeded(input: {
110
+ readonly namespace: StateNamespace;
111
+ readonly stackId: StackId;
112
+ readonly holderId: HolderId;
113
+ readonly observedAt: string;
114
+ }): Promise<LifecycleHistoryTransition>;
115
+ export {};
@@ -0,0 +1,398 @@
1
+ import { exactKeys } from '../exact-keys.js';
2
+ import { z } from 'zod';
3
+ import { lstatSync } from 'node:fs';
4
+ import { dirname, isAbsolute, relative, sep } from 'node:path';
5
+ import { hasErrorCode, RefusalError, ENVIRONMENT_CODES, isCanonicalTimestamp, snapshotJson, snapshotEnvironmentObservation, } from './contract.js';
6
+ import { abortStateTransaction, authenticateStateNamespace, lifecycleHistoryAddress, readState, transactState, withStateNamespaceInventory, } from './state.js';
7
+ import { stackId as deriveStackId } from './identity.js';
8
+ import { cockpitCommand } from '../fix-catalogue.js';
9
+ const OWNER = 'lifecycle-stage';
10
+ export const observationDeclarations = Object.freeze([{
11
+ id: 'state-seed',
12
+ owner: OWNER,
13
+ postures: ['environment'],
14
+ stages: [
15
+ { stage: 'bootstrap', disposition: 'not-applicable', reason: 'the first seed has not completed' },
16
+ { stage: 'steady', disposition: 'required' },
17
+ ],
18
+ code: ENVIRONMENT_CODES.STATE_UNSEEDED,
19
+ isIssued: isLifecycleStageObservation,
20
+ issuedAt: observationIssuedAt,
21
+ }]);
22
+ const HistoryValue = z.object({ status: z.enum(['started', 'seeded']) }).strict();
23
+ const STACK_ID = /^stack:[a-f0-9]{64}$/;
24
+ const HOLDER_ID = /^holder:[a-f0-9]{64}:session$/;
25
+ const AUTHORITY_LIFETIME_MS = 30_000;
26
+ const issuedObservations = new WeakMap();
27
+ const issuedAuthorities = new WeakMap();
28
+ const issuedLifecycleStageProjections = new WeakMap();
29
+ const lifecycleDigest = /^[a-f0-9]{64}$/;
30
+ const lifecycleService = /^[a-z0-9][a-z0-9_.-]*$/;
31
+ // A stack keeps the cockpit identity it started under, and that identity carries `cockpit.name`.
32
+ // After a rename this checkout's stack is still recorded under the earlier name, where sync, up and
33
+ // down no longer look: down reported nothing to act on while the containers kept running. This
34
+ // returns that earlier name while such a stack is recorded and not torn down, so they can refuse
35
+ // with the recovery instead.
36
+ export async function findStackUnderEarlierName(input) {
37
+ const [, currentName, checkoutDigest] = input.cockpitId.split(':');
38
+ const placeholder = `stack:${'0'.repeat(64)}`;
39
+ const found = await withStateNamespaceInventory(input.namespace, async (namespaces) => {
40
+ for (const candidate of namespaces) {
41
+ const cockpitId = candidate.paths.lifecycle(placeholder).cockpitId;
42
+ const [, name, digest] = cockpitId.split(':');
43
+ if (digest !== checkoutDigest || name === currentName || name === undefined)
44
+ continue;
45
+ const stack = deriveStackId({ cockpitId, checkoutId: input.checkoutId, variant: { kind: 'shared' } });
46
+ const address = candidate.paths.lifecycle(stack);
47
+ const stored = await readState(address);
48
+ if (stored.kind === 'missing')
49
+ continue;
50
+ if (stored.kind !== 'complete')
51
+ return { kind: 'refusal', code: stored.code, message: stored.message, target: stored.target };
52
+ const lifecycle = decodeLifecycleRecord(stored.value, { cockpitId, stackId: stack });
53
+ if (!lifecycle)
54
+ return { kind: 'refusal', code: ENVIRONMENT_CODES.STATE_RECORD_MALFORMED, message: 'lifecycle progress record is malformed', target: address.path };
55
+ if (lifecycle.value.teardownComplete !== true)
56
+ return { kind: 'complete', name };
57
+ }
58
+ return { kind: 'complete', name: undefined };
59
+ });
60
+ if (found.kind === 'complete')
61
+ return found.value;
62
+ if (found.kind === 'missing')
63
+ return { kind: 'complete', name: undefined };
64
+ return { kind: 'refusal', code: found.code, message: found.message, target: found.target };
65
+ }
66
+ export function earlierNameRefusalMessage(configPath, earlierName) {
67
+ return `cockpit.name was changed from "${earlierName}" while a stack started under that name is still recorded; the stack keeps the earlier name, so only down run under that name removes its containers — fix: set name = "${earlierName}" in ${configPath} again, run \`${cockpitCommand('down', { config: configPath })}\`, then rename the cockpit and run \`${cockpitCommand('sync', { config: configPath })}\``;
68
+ }
69
+ export function decodeLifecycleRecord(record, context) {
70
+ const value = snapshotJson(record.value);
71
+ if (!value || typeof value !== 'object' || Array.isArray(value)
72
+ || !exactKeys(value, ['completedServices', 'holderId', 'operationGeneration', 'workBasisSha256'], ['runtimeInputs', 'teardownComplete'])
73
+ || record.format !== 'cockpit-state/v1' || record.kind !== 'lifecycle'
74
+ || record.cockpitId !== context.cockpitId || record.subjectId !== context.stackId)
75
+ return undefined;
76
+ const candidate = value;
77
+ if (typeof candidate.holderId !== 'string' || !HOLDER_ID.test(candidate.holderId)
78
+ || typeof candidate.workBasisSha256 !== 'string' || !lifecycleDigest.test(candidate.workBasisSha256)
79
+ || typeof candidate.operationGeneration !== 'string' || !lifecycleDigest.test(candidate.operationGeneration)
80
+ || !Array.isArray(candidate.completedServices) || candidate.completedServices.length > 4_096)
81
+ return undefined;
82
+ const teardownComplete = Object.hasOwn(candidate, 'teardownComplete');
83
+ if (teardownComplete && (candidate.teardownComplete !== true || candidate.completedServices.length !== 0))
84
+ return undefined;
85
+ let runtimeInputs;
86
+ if (Object.hasOwn(candidate, 'runtimeInputs')) {
87
+ const value = candidate.runtimeInputs;
88
+ if (teardownComplete || !value || typeof value !== 'object' || Array.isArray(value))
89
+ return undefined;
90
+ const entries = Object.entries(value);
91
+ if (entries.length === 0 || entries.length > 64 || entries.some(([name, digest]) => name.length === 0 || name.length > 1_024
92
+ || name.includes('\0') || typeof digest !== 'string' || !lifecycleDigest.test(digest)))
93
+ return undefined;
94
+ runtimeInputs = Object.fromEntries(entries);
95
+ }
96
+ const completed = candidate.completedServices.map((item) => {
97
+ if (!item || typeof item !== 'object' || Array.isArray(item)
98
+ || !exactKeys(item, ['containerId', 'service']))
99
+ return undefined;
100
+ const service = item.service;
101
+ const containerId = item.containerId;
102
+ return typeof service === 'string' && lifecycleService.test(service)
103
+ && typeof containerId === 'string' && lifecycleDigest.test(containerId)
104
+ ? { service, containerId }
105
+ : undefined;
106
+ });
107
+ if (completed.some((item) => item === undefined))
108
+ return undefined;
109
+ return {
110
+ record,
111
+ value: {
112
+ holderId: candidate.holderId,
113
+ ...(teardownComplete ? { teardownComplete: true } : {}),
114
+ ...(runtimeInputs ? { runtimeInputs } : {}),
115
+ workBasisSha256: candidate.workBasisSha256,
116
+ operationGeneration: candidate.operationGeneration,
117
+ completedServices: completed,
118
+ },
119
+ };
120
+ }
121
+ function refusal(message, target) {
122
+ return {
123
+ kind: 'refusal',
124
+ diagnostics: [{
125
+ severity: 'error',
126
+ code: ENVIRONMENT_CODES.STATE_RECORD_MALFORMED,
127
+ message,
128
+ target,
129
+ fix: 'inspect lifecycle state and history before explicit recovery or adoption',
130
+ }],
131
+ };
132
+ }
133
+ function stableInput(value) {
134
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
135
+ return undefined;
136
+ const { namespace: rawNamespace, stackId, observedAt } = value;
137
+ const namespace = authenticateStateNamespace(rawNamespace);
138
+ const observedMillis = typeof observedAt === 'string' ? Date.parse(observedAt) : Number.NaN;
139
+ const now = Date.now();
140
+ if (!namespace || typeof stackId !== 'string' || !STACK_ID.test(stackId)
141
+ || !isCanonicalTimestamp(observedAt) || observedMillis > now || now - observedMillis > AUTHORITY_LIFETIME_MS)
142
+ return undefined;
143
+ return { namespace, stackId: stackId, observedAt };
144
+ }
145
+ function stableTransitionInput(value) {
146
+ const base = stableInput(value);
147
+ const holderId = base ? value.holderId : undefined;
148
+ return base && typeof holderId === 'string' && HOLDER_ID.test(holderId)
149
+ ? { ...base, holderId: holderId }
150
+ : undefined;
151
+ }
152
+ function historyStatus(record) {
153
+ return record.kind === 'lifecycle-history' ? HistoryValue.safeParse(record.value).data?.status : undefined;
154
+ }
155
+ function sameResult(left, right) {
156
+ return JSON.stringify(left) === JSON.stringify(right);
157
+ }
158
+ function fileIdentity(path) {
159
+ try {
160
+ const status = lstatSync(path, { bigint: true });
161
+ const state = status.isSymbolicLink() ? 'symlink'
162
+ : status.isFile() ? 'file'
163
+ : status.isDirectory() ? 'directory'
164
+ : 'other';
165
+ const identity = state === 'directory'
166
+ ? [status.dev, status.ino]
167
+ : [status.dev, status.ino, status.mode, status.size, status.mtimeNs, status.ctimeNs];
168
+ return { state, identity: identity.map(String).join(':') };
169
+ }
170
+ catch (error) {
171
+ return hasErrorCode(error, 'ENOENT')
172
+ ? { state: 'missing' }
173
+ : undefined;
174
+ }
175
+ }
176
+ function sameIdentity(left, right) {
177
+ return left.state === right.state && left.identity === right.identity;
178
+ }
179
+ function pathIdentity(root, path) {
180
+ const relation = relative(root, path);
181
+ if (!isAbsolute(root) || !isAbsolute(path) || relation === '' || isAbsolute(relation)
182
+ || relation === '..' || relation.startsWith(`..${sep}`))
183
+ return undefined;
184
+ const chain = [];
185
+ let cursor = path;
186
+ while (true) {
187
+ chain.push(cursor);
188
+ const parent = dirname(cursor);
189
+ if (parent === cursor)
190
+ break;
191
+ cursor = parent;
192
+ }
193
+ const identities = [];
194
+ for (const candidate of chain.reverse()) {
195
+ const identity = fileIdentity(candidate);
196
+ if (!identity)
197
+ return undefined;
198
+ identities.push(identity);
199
+ }
200
+ return identities;
201
+ }
202
+ function samePathIdentity(left, right) {
203
+ return left.length === right.length && left.every((identity, index) => sameIdentity(identity, right[index]));
204
+ }
205
+ function lifecycleBinding(namespace, cockpitId, historyPath, lifecyclePath) {
206
+ const historyIdentity = pathIdentity(namespace.root, historyPath);
207
+ const lifecycleIdentity = pathIdentity(namespace.root, lifecyclePath);
208
+ return historyIdentity && lifecycleIdentity
209
+ ? {
210
+ cockpitId,
211
+ namespace,
212
+ historyPath,
213
+ historyIdentity,
214
+ lifecyclePath,
215
+ lifecycleIdentity,
216
+ }
217
+ : undefined;
218
+ }
219
+ function sameBinding(left, right) {
220
+ return left.historyPath === right.historyPath
221
+ && left.lifecyclePath === right.lifecyclePath
222
+ && left.cockpitId === right.cockpitId
223
+ && samePathIdentity(left.historyIdentity, right.historyIdentity)
224
+ && samePathIdentity(left.lifecycleIdentity, right.lifecycleIdentity);
225
+ }
226
+ function issueObservation(value) {
227
+ const snapshot = snapshotEnvironmentObservation(value);
228
+ if (!snapshot || snapshot.owner !== OWNER)
229
+ throw new RefusalError('lifecycle stage observation is malformed');
230
+ issuedObservations.set(snapshot, Date.now());
231
+ return snapshot;
232
+ }
233
+ function isLifecycleStageObservation(value) {
234
+ return value !== null && typeof value === 'object' && issuedObservations.has(value);
235
+ }
236
+ function observationIssuedAt(value) {
237
+ return value !== null && typeof value === 'object' ? issuedObservations.get(value) : undefined;
238
+ }
239
+ async function inspect(input) {
240
+ const historyAddress = lifecycleHistoryAddress(input.namespace, input.stackId);
241
+ const lifecycleAddress = input.namespace.paths.lifecycle(input.stackId);
242
+ if (!historyAddress)
243
+ return refusal('lifecycle history address is unavailable', lifecycleAddress.path);
244
+ if (historyAddress.cockpitId !== lifecycleAddress.cockpitId) {
245
+ return refusal('lifecycle state addresses disagree on cockpit identity', historyAddress.path);
246
+ }
247
+ const bindingBefore = lifecycleBinding(input.namespace, historyAddress.cockpitId, historyAddress.path, lifecycleAddress.path);
248
+ if (!bindingBefore)
249
+ return refusal('lifecycle state identity is unavailable', historyAddress.path);
250
+ const historyBefore = await readState(historyAddress);
251
+ const lifecycleBefore = await readState(lifecycleAddress);
252
+ const historyAfter = await readState(historyAddress);
253
+ const lifecycleAfter = await readState(lifecycleAddress);
254
+ const bindingAfter = lifecycleBinding(input.namespace, historyAddress.cockpitId, historyAddress.path, lifecycleAddress.path);
255
+ if (!bindingAfter || !sameBinding(bindingBefore, bindingAfter)
256
+ || !sameResult(historyBefore, historyAfter) || !sameResult(lifecycleBefore, lifecycleAfter)) {
257
+ return refusal('lifecycle state changed while its stage was observed', historyAddress.path);
258
+ }
259
+ if (historyBefore.kind === 'refusal' || historyBefore.kind === 'indeterminate') {
260
+ return refusal(historyBefore.message, historyAddress.path);
261
+ }
262
+ if (lifecycleBefore.kind === 'refusal' || lifecycleBefore.kind === 'indeterminate') {
263
+ return refusal(lifecycleBefore.message, lifecycleAddress.path);
264
+ }
265
+ const status = historyBefore.kind === 'complete' ? historyStatus(historyBefore.value) : undefined;
266
+ if (historyBefore.kind === 'complete' && !status)
267
+ return refusal('lifecycle history is malformed', historyAddress.path);
268
+ if (historyBefore.kind === 'missing' && lifecycleBefore.kind === 'complete') {
269
+ return refusal('lifecycle data exists without durable lifecycle history', lifecycleAddress.path);
270
+ }
271
+ const stage = status === 'seeded' ? 'steady' : 'bootstrap';
272
+ const seeded = lifecycleBefore.kind === 'complete';
273
+ const issuedAt = Date.now();
274
+ const authority = {
275
+ stackId: input.stackId,
276
+ stage,
277
+ observedAt: input.observedAt,
278
+ validThrough: new Date(issuedAt + AUTHORITY_LIFETIME_MS).toISOString(),
279
+ };
280
+ issuedAuthorities.set(authority, bindingAfter);
281
+ const observation = issueObservation({
282
+ code: ENVIRONMENT_CODES.STATE_UNSEEDED,
283
+ owner: OWNER,
284
+ stackId: input.stackId,
285
+ source: lifecycleAddress.path,
286
+ observed: { state: 'available', value: seeded, observedAt: input.observedAt },
287
+ expectation: { kind: 'equal', value: true },
288
+ applicability: { state: 'required', posture: 'environment' },
289
+ freshness: { state: 'current' },
290
+ remedy: 'restore or seed lifecycle state without deleting its durable history',
291
+ });
292
+ return { kind: 'complete', authority, observation };
293
+ }
294
+ export async function resolveLifecycleStage(input) {
295
+ const stable = stableInput(input);
296
+ return stable ? inspect(stable) : refusal('lifecycle stage input is malformed', 'lifecycle stage input');
297
+ }
298
+ export async function observeStateSeed(input) {
299
+ const result = await resolveLifecycleStage(input);
300
+ if (result.kind !== 'complete')
301
+ throw new RefusalError(result.diagnostics[0]?.message ?? 'lifecycle stage is unavailable');
302
+ return result.observation;
303
+ }
304
+ function validAuthorityExpectation(value) {
305
+ return Number.isSafeInteger(value.earliest)
306
+ && Number.isSafeInteger(value.latest)
307
+ && Number.isSafeInteger(value.evaluatedAt)
308
+ && value.earliest <= value.evaluatedAt
309
+ && value.evaluatedAt <= value.latest;
310
+ }
311
+ function consumeLifecycleStageAuthority(value, expected, trustedCurrentTime) {
312
+ if (value === null || typeof value !== 'object' || !validAuthorityExpectation(expected)
313
+ || !Number.isSafeInteger(trustedCurrentTime) || expected.evaluatedAt > trustedCurrentTime)
314
+ return undefined;
315
+ const binding = issuedAuthorities.get(value);
316
+ if (!binding || binding.cockpitId !== expected.cockpitId)
317
+ return undefined;
318
+ const authority = value;
319
+ const observedAt = Date.parse(authority.observedAt);
320
+ const validThrough = Date.parse(authority.validThrough);
321
+ if (authority.stackId !== expected.stackId || !Number.isFinite(observedAt) || !Number.isFinite(validThrough)
322
+ || observedAt < expected.earliest || observedAt > expected.latest
323
+ || observedAt > expected.evaluatedAt || trustedCurrentTime > validThrough)
324
+ return undefined;
325
+ const namespace = authenticateStateNamespace(binding.namespace);
326
+ const currentBinding = namespace
327
+ ? lifecycleBinding(namespace, binding.cockpitId, binding.historyPath, binding.lifecyclePath)
328
+ : undefined;
329
+ if (!currentBinding || !sameBinding(binding, currentBinding))
330
+ return undefined;
331
+ issuedAuthorities.delete(value);
332
+ return authority.stage;
333
+ }
334
+ export function authenticateLifecycleStageAuthority(value, stackId, cockpitId, earliest, latest, evaluatedAt) {
335
+ return consumeLifecycleStageAuthority(value, { stackId, cockpitId, earliest, latest, evaluatedAt }, evaluatedAt);
336
+ }
337
+ export function projectLifecycleStage(input) {
338
+ const expected = { stackId: input.stackId, cockpitId: input.cockpitId, earliest: input.earliest, latest: input.latest, evaluatedAt: input.evaluatedAt };
339
+ const stage = consumeLifecycleStageAuthority(input.authority, expected, Date.now());
340
+ if (!stage)
341
+ return undefined;
342
+ const projection = {};
343
+ issuedLifecycleStageProjections.set(projection, Object.freeze({ stackId: expected.stackId, stage }));
344
+ return projection;
345
+ }
346
+ export function consumeLifecycleStageProjection(projection) {
347
+ const evidence = issuedLifecycleStageProjections.get(projection);
348
+ if (!evidence)
349
+ return undefined;
350
+ issuedLifecycleStageProjections.delete(projection);
351
+ return evidence;
352
+ }
353
+ async function transition(value, requested) {
354
+ const input = stableTransitionInput(value);
355
+ if (!input)
356
+ return refusal('lifecycle history transition input is malformed', 'lifecycle history input');
357
+ const address = lifecycleHistoryAddress(input.namespace, input.stackId);
358
+ if (!address)
359
+ return refusal('lifecycle history address is unavailable', input.stackId);
360
+ const result = await transactState(input.namespace, address, { ownerId: input.holderId }, (current) => {
361
+ const currentStatus = current ? historyStatus(current) : undefined;
362
+ if (current && !currentStatus)
363
+ return abortStateTransaction(refusal('lifecycle history is malformed', address.path));
364
+ if (requested === 'seeded' && currentStatus === undefined) {
365
+ return abortStateTransaction(refusal('lifecycle history must be started before it is seeded', address.path));
366
+ }
367
+ // Seeded history already records its start, so a later `started` (setup acquiring a
368
+ // sibling added after the stack has run) leaves it seeded. Refusing it deadlocked setup.
369
+ if (currentStatus === requested || currentStatus === 'seeded') {
370
+ return abortStateTransaction({ kind: 'unchanged', record: current });
371
+ }
372
+ return {
373
+ format: 'cockpit-state/v1',
374
+ kind: 'lifecycle-history',
375
+ cockpitId: address.cockpitId,
376
+ subjectId: input.stackId,
377
+ revision: (current?.revision ?? -1) + 1,
378
+ updatedAt: input.observedAt,
379
+ value: { status: requested },
380
+ };
381
+ });
382
+ const aborted = result;
383
+ if (aborted.aborted === true)
384
+ return aborted.value;
385
+ const stateResult = result;
386
+ if (stateResult.kind === 'complete')
387
+ return { kind: 'complete', record: stateResult.value };
388
+ const message = stateResult.kind === 'refusal' || stateResult.kind === 'indeterminate'
389
+ ? stateResult.message
390
+ : 'lifecycle history transition failed';
391
+ return refusal(message, address.path);
392
+ }
393
+ export function recordLifecycleStarted(input) {
394
+ return transition(input, 'started');
395
+ }
396
+ export function recordLifecycleSeeded(input) {
397
+ return transition(input, 'seeded');
398
+ }
@@ -0,0 +1,75 @@
1
+ import { type EnvironmentDiagnostic, type LifecyclePlan, type LifecycleProgress } from './contract.js';
2
+ import { type LifecycleStageProjection } from './lifecycle-stage.js';
3
+ import { type PortLeaseProjection } from './ports.js';
4
+ import type { ReclaimTargetEnvelope } from './reclaim.js';
5
+ import { type RuntimeLifecycleProjection, type RuntimeServiceEvidence, type RuntimeTopologyEvidence } from './runtime.js';
6
+ import type { DrainReservationRequest } from './claims.js';
7
+ type PortOwnership = PortLeaseProjection['ownership'];
8
+ export interface LifecycleIssuance {
9
+ readonly topology: RuntimeTopologyEvidence;
10
+ readonly firstIncompleteServiceIndex: number;
11
+ readonly portOwnership: PortOwnership;
12
+ readonly drainRequest: DrainReservationRequest | null;
13
+ readonly reclaim: ReclaimTargetEnvelope | null;
14
+ }
15
+ export type UpLifecycleResult = {
16
+ readonly kind: 'execute';
17
+ readonly mode: 'start' | 'resume';
18
+ readonly plan: LifecyclePlan;
19
+ } | {
20
+ readonly kind: 'noop';
21
+ readonly plan: LifecyclePlan;
22
+ } | LifecycleRefusal;
23
+ export type SleepLifecycleResult = {
24
+ readonly kind: 'release-only';
25
+ readonly plan: LifecyclePlan;
26
+ } | {
27
+ readonly kind: 'drain';
28
+ readonly plan: LifecyclePlan;
29
+ readonly request: DrainReservationRequest;
30
+ } | LifecycleRefusal;
31
+ export type DestructiveLifecycleResult = {
32
+ readonly kind: 'drain';
33
+ readonly plan: LifecyclePlan;
34
+ readonly request: DrainReservationRequest;
35
+ } | LifecycleRefusal;
36
+ type LifecycleRefusal = {
37
+ readonly kind: 'refusal';
38
+ readonly diagnostics: readonly EnvironmentDiagnostic[];
39
+ };
40
+ declare const upPlanningAuthorityBrand: unique symbol;
41
+ export interface UpPlanningAuthority {
42
+ readonly [upPlanningAuthorityBrand]: true;
43
+ }
44
+ export declare function consumeLifecycleIssuance(plan: LifecyclePlan): LifecycleIssuance | undefined;
45
+ export declare function admitUpProgress(input: {
46
+ readonly lifecycleStage: LifecycleStageProjection;
47
+ readonly runtime: RuntimeLifecycleProjection;
48
+ readonly ports: PortLeaseProjection;
49
+ readonly progress: LifecycleProgress | null;
50
+ readonly operationGeneration: string;
51
+ }): {
52
+ readonly kind: 'admitted';
53
+ readonly authority: UpPlanningAuthority;
54
+ } | LifecycleRefusal;
55
+ export declare function planAdmittedUp(input: {
56
+ readonly authority: UpPlanningAuthority;
57
+ readonly completedServices: readonly RuntimeServiceEvidence[];
58
+ }): UpLifecycleResult;
59
+ export declare function planSleep(input: {
60
+ readonly runtime: RuntimeLifecycleProjection;
61
+ readonly ports: PortLeaseProjection;
62
+ readonly operationGeneration: string;
63
+ readonly runtimeStopValidForMs: number;
64
+ }): SleepLifecycleResult;
65
+ interface DestructivePlanningInput {
66
+ readonly runtime: RuntimeLifecycleProjection;
67
+ readonly ports: PortLeaseProjection;
68
+ readonly reclaim: ReclaimTargetEnvelope;
69
+ readonly operationGeneration: string;
70
+ readonly runtimeStopValidForMs: number;
71
+ readonly reclaimValidForMs: number;
72
+ }
73
+ export declare function planDown(input: DestructivePlanningInput): DestructiveLifecycleResult;
74
+ export declare function planResetLifecycle(input: DestructivePlanningInput): DestructiveLifecycleResult;
75
+ export {};