@volter/world-runtime 2.0.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 (164) hide show
  1. package/LICENSE +202 -0
  2. package/dist/known-external-services.json +1108 -0
  3. package/dist/src/ancestry.d.ts +2 -0
  4. package/dist/src/ancestry.js +42 -0
  5. package/dist/src/app-url.d.ts +47 -0
  6. package/dist/src/app-url.js +239 -0
  7. package/dist/src/attach.d.ts +48 -0
  8. package/dist/src/attach.js +87 -0
  9. package/dist/src/branch.d.ts +20 -0
  10. package/dist/src/branch.js +65 -0
  11. package/dist/src/browser-proxy-cli.d.ts +2 -0
  12. package/dist/src/browser-proxy-cli.js +41 -0
  13. package/dist/src/ca-trust.d.ts +5 -0
  14. package/dist/src/ca-trust.js +64 -0
  15. package/dist/src/catalog.d.ts +31 -0
  16. package/dist/src/catalog.js +148 -0
  17. package/dist/src/changeset.d.ts +142 -0
  18. package/dist/src/changeset.js +570 -0
  19. package/dist/src/cli.d.ts +2 -0
  20. package/dist/src/cli.js +1262 -0
  21. package/dist/src/command-lifetime.d.ts +15 -0
  22. package/dist/src/command-lifetime.js +98 -0
  23. package/dist/src/configs.d.ts +18 -0
  24. package/dist/src/configs.js +119 -0
  25. package/dist/src/console-apart.d.ts +38 -0
  26. package/dist/src/console-apart.js +107 -0
  27. package/dist/src/consumers.d.ts +46 -0
  28. package/dist/src/consumers.js +200 -0
  29. package/dist/src/covers.d.ts +183 -0
  30. package/dist/src/covers.js +800 -0
  31. package/dist/src/fixture-env.d.ts +42 -0
  32. package/dist/src/fixture-env.js +221 -0
  33. package/dist/src/host-cli.d.ts +2 -0
  34. package/dist/src/host-cli.js +92 -0
  35. package/dist/src/host-fault-fixture.d.ts +32 -0
  36. package/dist/src/host-fault-fixture.js +100 -0
  37. package/dist/src/host-worker.d.ts +1 -0
  38. package/dist/src/host-worker.js +23 -0
  39. package/dist/src/host.d.ts +38 -0
  40. package/dist/src/host.js +135 -0
  41. package/dist/src/index.d.ts +48 -0
  42. package/dist/src/index.js +35 -0
  43. package/dist/src/infra-cli.d.ts +2 -0
  44. package/dist/src/infra-cli.js +136 -0
  45. package/dist/src/init.d.ts +227 -0
  46. package/dist/src/init.js +1117 -0
  47. package/dist/src/inject-map.d.ts +34 -0
  48. package/dist/src/inject-map.js +56 -0
  49. package/dist/src/lifecycle-record.d.ts +47 -0
  50. package/dist/src/lifecycle-record.js +196 -0
  51. package/dist/src/origin.d.ts +31 -0
  52. package/dist/src/origin.js +139 -0
  53. package/dist/src/pack-facts.d.ts +75 -0
  54. package/dist/src/pack-facts.js +98 -0
  55. package/dist/src/pglite-backing.d.ts +21 -0
  56. package/dist/src/pglite-backing.js +158 -0
  57. package/dist/src/pglite-host.mjs +147 -0
  58. package/dist/src/placeholder.d.ts +20 -0
  59. package/dist/src/placeholder.js +100 -0
  60. package/dist/src/prerequisites.d.ts +21 -0
  61. package/dist/src/prerequisites.js +49 -0
  62. package/dist/src/process-groups.d.ts +4 -0
  63. package/dist/src/process-groups.js +49 -0
  64. package/dist/src/project-inspect.d.ts +109 -0
  65. package/dist/src/project-inspect.js +827 -0
  66. package/dist/src/proxy-daemon.d.ts +2 -0
  67. package/dist/src/proxy-daemon.js +18 -0
  68. package/dist/src/redirect-proxy.d.ts +105 -0
  69. package/dist/src/redirect-proxy.js +665 -0
  70. package/dist/src/reflect.d.ts +74 -0
  71. package/dist/src/reflect.js +392 -0
  72. package/dist/src/resources.d.ts +26 -0
  73. package/dist/src/resources.js +22 -0
  74. package/dist/src/root.d.ts +114 -0
  75. package/dist/src/root.js +312 -0
  76. package/dist/src/run-task-worker.d.ts +1 -0
  77. package/dist/src/run-task-worker.js +38 -0
  78. package/dist/src/run-task.d.ts +18 -0
  79. package/dist/src/run-task.js +48 -0
  80. package/dist/src/runtime-test-support.d.ts +59 -0
  81. package/dist/src/runtime-test-support.js +205 -0
  82. package/dist/src/runtime.d.ts +256 -0
  83. package/dist/src/runtime.js +3502 -0
  84. package/dist/src/schema.d.ts +449 -0
  85. package/dist/src/schema.js +605 -0
  86. package/dist/src/serve.d.ts +30 -0
  87. package/dist/src/serve.js +82 -0
  88. package/dist/src/served-world.d.ts +194 -0
  89. package/dist/src/served-world.js +986 -0
  90. package/dist/src/service-exit.d.ts +46 -0
  91. package/dist/src/service-exit.js +195 -0
  92. package/dist/src/service-recorder.d.ts +1 -0
  93. package/dist/src/service-recorder.js +121 -0
  94. package/dist/src/sibling.d.ts +1 -0
  95. package/dist/src/sibling.js +9 -0
  96. package/dist/src/signals.d.ts +1 -0
  97. package/dist/src/signals.js +11 -0
  98. package/dist/src/storage-capacity.d.ts +8 -0
  99. package/dist/src/storage-capacity.js +61 -0
  100. package/dist/src/tail.d.ts +30 -0
  101. package/dist/src/tail.js +160 -0
  102. package/dist/src/tcp-port.d.ts +2 -0
  103. package/dist/src/tcp-port.js +36 -0
  104. package/dist/src/up-task-worker.d.ts +1 -0
  105. package/dist/src/up-task-worker.js +61 -0
  106. package/dist/src/up-task.d.ts +17 -0
  107. package/dist/src/up-task.js +49 -0
  108. package/dist/src/websocket-relay.d.ts +3 -0
  109. package/dist/src/websocket-relay.js +40 -0
  110. package/known-external-services.json +1108 -0
  111. package/package.json +83 -0
  112. package/src/ancestry.ts +36 -0
  113. package/src/app-url.ts +253 -0
  114. package/src/attach.ts +117 -0
  115. package/src/branch.ts +63 -0
  116. package/src/browser-proxy-cli.ts +44 -0
  117. package/src/ca-trust.ts +57 -0
  118. package/src/catalog.ts +156 -0
  119. package/src/changeset.ts +627 -0
  120. package/src/cli.ts +1111 -0
  121. package/src/command-lifetime.ts +79 -0
  122. package/src/configs.ts +110 -0
  123. package/src/console-apart.ts +90 -0
  124. package/src/consumers.ts +185 -0
  125. package/src/covers.ts +934 -0
  126. package/src/fixture-env.ts +230 -0
  127. package/src/host-cli.ts +90 -0
  128. package/src/host-worker.ts +23 -0
  129. package/src/host.ts +169 -0
  130. package/src/index.ts +171 -0
  131. package/src/infra-cli.ts +133 -0
  132. package/src/init.ts +1316 -0
  133. package/src/inject-map.ts +72 -0
  134. package/src/lifecycle-record.ts +168 -0
  135. package/src/origin.ts +134 -0
  136. package/src/pack-facts.ts +128 -0
  137. package/src/pglite-backing.ts +141 -0
  138. package/src/pglite-host.mjs +147 -0
  139. package/src/placeholder.ts +89 -0
  140. package/src/prerequisites.ts +66 -0
  141. package/src/process-groups.ts +33 -0
  142. package/src/project-inspect.ts +770 -0
  143. package/src/proxy-daemon.ts +21 -0
  144. package/src/redirect-proxy.ts +684 -0
  145. package/src/reflect.ts +440 -0
  146. package/src/resources.ts +22 -0
  147. package/src/root.ts +290 -0
  148. package/src/run-task-worker.ts +27 -0
  149. package/src/run-task.ts +44 -0
  150. package/src/runtime-test-support.ts +208 -0
  151. package/src/runtime.ts +3357 -0
  152. package/src/schema.ts +922 -0
  153. package/src/serve.ts +102 -0
  154. package/src/served-world.ts +812 -0
  155. package/src/service-exit.ts +175 -0
  156. package/src/service-recorder.ts +89 -0
  157. package/src/sibling.ts +10 -0
  158. package/src/signals.ts +10 -0
  159. package/src/storage-capacity.ts +60 -0
  160. package/src/tail.ts +205 -0
  161. package/src/tcp-port.ts +35 -0
  162. package/src/up-task-worker.ts +40 -0
  163. package/src/up-task.ts +45 -0
  164. package/src/websocket-relay.ts +32 -0
@@ -0,0 +1,64 @@
1
+ import { createHash, randomUUID, X509Certificate } from 'node:crypto';
2
+ import { existsSync, readFileSync, writeFileSync, renameSync, rmSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import * as tls from 'node:tls';
5
+ export class CaTrustError extends Error {
6
+ }
7
+ /** Per-client trust, materialized only when a caller attaches. Never modify the signing CA. */
8
+ export function sessionTrustEnv(caCertPath, inputs = process.env) {
9
+ const callers = Array.isArray(inputs) ? inputs : [inputs];
10
+ const files = new Map();
11
+ const read = (path) => {
12
+ if (files.has(path))
13
+ return files.get(path);
14
+ try {
15
+ const contents = readFileSync(path, 'utf8');
16
+ const pattern = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
17
+ const certificates = contents.match(pattern) ?? [];
18
+ if (!certificates.length || /-----BEGIN|-----END/.test(contents.replace(pattern, '')))
19
+ throw new Error('expected complete PEM certificates');
20
+ const pem = certificates.map(cert => new X509Certificate(cert).toString().trim()).join('\n');
21
+ files.set(path, pem);
22
+ return pem;
23
+ }
24
+ catch (error) {
25
+ throw new CaTrustError(`Cannot read configured CA file ${path}: ${String(error)}`);
26
+ }
27
+ };
28
+ const session = read(caCertPath);
29
+ const extra = callers.flatMap(caller => caller.NODE_EXTRA_CA_CERTS ? [read(caller.NODE_EXTRA_CA_CERTS)] : []).join('\n');
30
+ // getCACertificates is newer than our minimum Node version; bundled roots also cover callers
31
+ // whose current OpenSSL defaults have already been replaced by a session-only CA file.
32
+ const defaults = typeof tls.getCACertificates === 'function' ? tls.getCACertificates('default') : [];
33
+ const publicRoots = [...new Set([...tls.rootCertificates, ...defaults].map(cert => new X509Certificate(cert).toString().trim()))].join('\n');
34
+ const bundle = (contents) => {
35
+ const certificates = contents.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) ?? [];
36
+ const pem = `${[...new Set(certificates.map(cert => cert.trim()))].sort().join('\n')}\n`;
37
+ const path = join(dirname(caCertPath), `trust-${createHash('sha256').update(pem).digest('hex')}.pem`);
38
+ const temporary = `${path}.${randomUUID()}.tmp`;
39
+ try {
40
+ if (!existsSync(path) || readFileSync(path, 'utf8') !== pem) {
41
+ writeFileSync(temporary, pem, { flag: 'wx', mode: 0o600 });
42
+ renameSync(temporary, path);
43
+ }
44
+ }
45
+ catch (error) {
46
+ try {
47
+ rmSync(temporary, { force: true });
48
+ }
49
+ catch (cleanupError) {
50
+ throw new CaTrustError(`Cannot materialize session trust bundle: ${String(error)}; cleanup: ${String(cleanupError)}`);
51
+ }
52
+ throw new CaTrustError(`Cannot materialize session trust bundle: ${String(error)}`);
53
+ }
54
+ return path;
55
+ };
56
+ const env = {
57
+ NODE_EXTRA_CA_CERTS: extra ? bundle(`${extra}\n${session}`) : caCertPath,
58
+ };
59
+ for (const key of ['SSL_CERT_FILE', 'REQUESTS_CA_BUNDLE', 'CURL_CA_BUNDLE', 'AWS_CA_BUNDLE', 'GIT_SSL_CAINFO']) {
60
+ const configured = callers.flatMap(caller => caller[key] ? [read(caller[key])] : []).join('\n');
61
+ env[key] = bundle(`${publicRoots}\n${extra}\n${configured}\n${session}`);
62
+ }
63
+ return env;
64
+ }
@@ -0,0 +1,31 @@
1
+ export declare const TWIN_PACKAGE_PREFIX = "@volter/twin-";
2
+ /** Packages under the `@volter/twin-` prefix that are NOT twins. */
3
+ export declare function twinPackageName(vendor: string): string;
4
+ export type CatalogKind = 'checkout' | 'installed';
5
+ export type Catalog = {
6
+ kind: CatalogKind;
7
+ /** The world root the catalog was resolved for. */
8
+ root: string;
9
+ /** Every vendor the catalog can run, sorted — a deterministic input to `init`. */
10
+ vendors(): string[];
11
+ /** The pack's directory (holds `src/cli.ts`, `src/index.ts`, `defaults/`, `package.json`), or undefined. */
12
+ packDir(vendor: string): string | undefined;
13
+ /** The pack's own version, from its package.json — the value a world's pin carries. */
14
+ version(vendor: string): string | undefined;
15
+ /** The birth stamp: the checkout's git sha, or a digest of the installed versions. */
16
+ sha(): string;
17
+ };
18
+ /** The pack's module entry, FROM ITS MANIFEST (docs/contributing/architecture.md#the-publishing-pipeline): `exports['.']`
19
+ * — `src/index.ts` in the checkout, `dist/src/index.js` once published — so the same resolution
20
+ * serves both; `main` behind it; the checkout convention last. */
21
+ export declare function packEntry(dir: string): string;
22
+ /** The pack's cli, from its manifest's `bin` (`world-<vendor>` when named, else the first), or undefined when the directory is no pack. */
23
+ export declare function packCli(dir: string): string | undefined;
24
+ /** The nearest `node_modules/<name>` above `from` that holds a package.json — node's own walk. */
25
+ export declare function findInstalledPackage(from: string, name: string): string | undefined;
26
+ export declare function checkoutCatalog(root: string): Catalog;
27
+ export declare function installedCatalog(root: string): Catalog;
28
+ /** The catalog for a world root: the checkout when `packages/twin` is there, else what is installed. */
29
+ export declare function resolveCatalog(root: string): Catalog;
30
+ /** The pack directory a service boots from: its `package` resolved from the world root at boot. */
31
+ export declare function resolveServicePackage(root: string, pkg: string): string;
@@ -0,0 +1,148 @@
1
+ // The catalog — where the twins a world can run come from (docs/concepts/worlds.md
2
+ // #the-config-and-the-running-world). Two sources answer one interface: this CHECKOUT (`packages/twin/<vendor>/`, the
3
+ // catalog as the repo holds it) and an INSTALLED catalog (`@volter/twin-<vendor>` packages under
4
+ // `node_modules`, walked up from the world root — hoisting-proof, and independent of the
5
+ // packages' `exports` maps, which do not expose `package.json`). A world born in an app repo
6
+ // names its twins as packages and the runtime resolves them at boot; a world born here names the
7
+ // checkout-relative paths, as before.
8
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
9
+ import { spawnSync } from 'node:child_process';
10
+ import { dirname, join, resolve } from 'node:path';
11
+ export const TWIN_PACKAGE_PREFIX = '@volter/twin-';
12
+ /** Packages under the `@volter/twin-` prefix that are NOT twins. */
13
+ export function twinPackageName(vendor) { return `${TWIN_PACKAGE_PREFIX}${vendor}`; }
14
+ function packageVersion(dir) {
15
+ const p = join(dir, 'package.json');
16
+ if (!existsSync(p))
17
+ return undefined;
18
+ try {
19
+ const v = JSON.parse(readFileSync(p, 'utf8')).version;
20
+ return typeof v === 'string' ? v : undefined;
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ }
26
+ function isPackDir(dir) { return packCli(dir) !== undefined; }
27
+ function manifest(dir) { const p = join(dir, 'package.json'); if (!existsSync(p))
28
+ return undefined; try {
29
+ return JSON.parse(readFileSync(p, 'utf8'));
30
+ }
31
+ catch {
32
+ return undefined;
33
+ } }
34
+ /** The pack's module entry, FROM ITS MANIFEST (docs/contributing/architecture.md#the-publishing-pipeline): `exports['.']`
35
+ * — `src/index.ts` in the checkout, `dist/src/index.js` once published — so the same resolution
36
+ * serves both; `main` behind it; the checkout convention last. */
37
+ export function packEntry(dir) {
38
+ const m = manifest(dir);
39
+ const dot = m?.exports === undefined ? undefined : typeof m.exports === 'string' ? m.exports : m.exports['.'];
40
+ const value = typeof dot === 'string' ? dot : dot && typeof dot === 'object' ? (dot.default ?? dot.import) : undefined;
41
+ const rel = typeof value === 'string' ? value : typeof m?.main === 'string' ? m.main : 'src/index.ts';
42
+ return join(dir, rel);
43
+ }
44
+ /** The pack's cli, from its manifest's `bin` (`world-<vendor>` when named, else the first), or undefined when the directory is no pack. */
45
+ export function packCli(dir) {
46
+ const m = manifest(dir);
47
+ const bins = m === undefined ? {} : typeof m.bin === 'string' ? { [m.name ?? 'cli']: m.bin } : m.bin ?? {};
48
+ const named = Object.entries(bins).find(([n]) => n.startsWith('world-'))?.[1] ?? Object.values(bins)[0];
49
+ if (named)
50
+ return join(dir, named);
51
+ return existsSync(join(dir, 'src', 'cli.ts')) ? join(dir, 'src', 'cli.ts') : undefined;
52
+ }
53
+ /** The nearest `node_modules/<name>` above `from` that holds a package.json — node's own walk. */
54
+ export function findInstalledPackage(from, name) {
55
+ let dir = resolve(from);
56
+ for (;;) {
57
+ const candidate = join(dir, 'node_modules', ...name.split('/'));
58
+ if (existsSync(join(candidate, 'package.json')))
59
+ return candidate;
60
+ const up = dirname(dir);
61
+ if (up === dir)
62
+ return undefined;
63
+ dir = up;
64
+ }
65
+ }
66
+ /** Every installed `@volter/twin-<vendor>` visible from `from`, nearest wins. */
67
+ function installedTwins(from) {
68
+ const found = new Map();
69
+ let dir = resolve(from);
70
+ for (;;) {
71
+ const scope = join(dir, 'node_modules', '@volter');
72
+ if (existsSync(scope)) {
73
+ for (const entry of readdirSync(scope, { withFileTypes: true })) {
74
+ if (!entry.isDirectory() && !entry.isSymbolicLink())
75
+ continue;
76
+ const name = `@volter/${entry.name}`;
77
+ if (!name.startsWith(TWIN_PACKAGE_PREFIX))
78
+ continue; // the platform's packages are `@volter/world-*`: outside the prefix by name
79
+ const vendor = name.slice(TWIN_PACKAGE_PREFIX.length);
80
+ const packDir = join(scope, entry.name);
81
+ if (!found.has(vendor) && isPackDir(packDir))
82
+ found.set(vendor, packDir);
83
+ }
84
+ }
85
+ const up = dirname(dir);
86
+ if (up === dir)
87
+ break;
88
+ dir = up;
89
+ }
90
+ return found;
91
+ }
92
+ function fnv1a(text) {
93
+ let h = 0x811c9dc5;
94
+ for (let i = 0; i < text.length; i += 1) {
95
+ h ^= text.charCodeAt(i);
96
+ h = Math.imul(h, 0x01000193) >>> 0;
97
+ }
98
+ return h.toString(16).padStart(8, '0');
99
+ }
100
+ export function checkoutCatalog(root) {
101
+ const packsDir = resolve(root, 'packages', 'twin');
102
+ const vendors = () => readdirSync(packsDir, { withFileTypes: true })
103
+ .filter((entry) => entry.isDirectory() && isPackDir(join(packsDir, entry.name)))
104
+ .map((entry) => entry.name)
105
+ .sort();
106
+ return {
107
+ kind: 'checkout',
108
+ root: resolve(root),
109
+ vendors,
110
+ packDir: (vendor) => (isPackDir(join(packsDir, vendor)) ? join(packsDir, vendor) : undefined),
111
+ version: (vendor) => packageVersion(join(packsDir, vendor)),
112
+ sha: () => {
113
+ const proc = spawnSync('git', ['-C', root, 'rev-parse', 'HEAD'], { encoding: 'utf8' });
114
+ const sha = proc.status === 0 ? proc.stdout.trim() : '';
115
+ return /^[0-9a-f]{40}$/.test(sha) ? sha : 'unknown';
116
+ },
117
+ };
118
+ }
119
+ export function installedCatalog(root) {
120
+ const twins = installedTwins(root);
121
+ return {
122
+ kind: 'installed',
123
+ root: resolve(root),
124
+ vendors: () => [...twins.keys()].sort(),
125
+ packDir: (vendor) => twins.get(vendor),
126
+ version: (vendor) => { const dir = twins.get(vendor); return dir === undefined ? undefined : packageVersion(dir); },
127
+ sha: () => `installed-${fnv1a([...twins.keys()].sort().map((v) => `${v}@${packageVersion(twins.get(v)) ?? '?'}`).join(','))}`,
128
+ };
129
+ }
130
+ /** The catalog for a world root: the checkout when `packages/twin` is there, else what is installed. */
131
+ export function resolveCatalog(root) {
132
+ const resolved = resolve(root);
133
+ if (existsSync(join(resolved, 'packages', 'twin')))
134
+ return checkoutCatalog(resolved);
135
+ const installed = installedCatalog(resolved);
136
+ if (installed.vendors().length === 0) {
137
+ throw new Error(`No twins found for ${resolved}: no \`packages/twin\` catalog here and no \`@volter/twin-<vendor>\` package installed above it. `
138
+ + `Install the twins your app needs (e.g. \`bun add -d @volter/twin-stripe\`) and run init again.`);
139
+ }
140
+ return installed;
141
+ }
142
+ /** The pack directory a service boots from: its `package` resolved from the world root at boot. */
143
+ export function resolveServicePackage(root, pkg) {
144
+ const dir = findInstalledPackage(root, pkg);
145
+ if (dir === undefined)
146
+ throw new Error(`Twin package ${pkg} is not installed above ${root} — \`bun add -d ${pkg}\` (or npm/pnpm) and run up again`);
147
+ return dir;
148
+ }
@@ -0,0 +1,142 @@
1
+ import type { ChangesetApplication, RebaseReport, Changeset, ChangesetApproval, ChangesetReadiness, ChangesetVerification, ChangesetVerifier, LedgerDelta, LedgerRef, ReplayReport, WorldMarker } from '@volter/world-core';
2
+ export type WorldRootOptions = {
3
+ root?: string;
4
+ };
5
+ /** Every action ledger in a world, as control-plane ledger references. */
6
+ export declare function worldLedgers(name: string, root?: string): LedgerRef[];
7
+ export declare function worldMarksDir(name: string, root?: string): string;
8
+ export declare function worldChangesetsDir(name: string, root?: string): string;
9
+ /** Capture a cross-service base marker for `world` and persist it. */
10
+ /** A world mark with the note it was taken with, if any: what the moment was, in words (a commit's message). The
11
+ * note is the runtime's, beside world-core's marker, which reads no field of it. */
12
+ export type NotedMarker = WorldMarker & {
13
+ note?: string;
14
+ };
15
+ /** The longest note a mark keeps; a longer one is cut. */
16
+ export declare const MARK_NOTE_MAX = 600;
17
+ export declare function markWorld(name: string, options?: WorldRootOptions & {
18
+ id?: string;
19
+ now?: Date;
20
+ note?: string;
21
+ }): NotedMarker;
22
+ /** Every mark recorded in a world, oldest first. */
23
+ export declare function listWorldMarks(name: string, root?: string): NotedMarker[];
24
+ /**
25
+ * The base a diff/changeset is taken against:
26
+ * explicit `--base <id>` → that mark (which must belong to THIS world),
27
+ * otherwise the world's most recent mark,
28
+ * otherwise `world-boot` — position 0 on every ledger, i.e. everything this world recorded.
29
+ *
30
+ * `--base world-boot` is spellable explicitly, so "show me the whole session" never requires
31
+ * deleting marks.
32
+ */
33
+ export declare function resolveBaseMarker(name: string, options?: WorldRootOptions & {
34
+ base?: string;
35
+ }): WorldMarker;
36
+ /** The world's ledger delta since `base` (default: the last mark, else world-boot). */
37
+ export declare function diffWorld(name: string, options?: WorldRootOptions & {
38
+ base?: string;
39
+ }): LedgerDelta;
40
+ export type ChangesetLocation = {
41
+ changeset: Changeset;
42
+ world: string;
43
+ path: string;
44
+ };
45
+ /** Freeze the current delta into `<world>/changesets/<name>.json`. */
46
+ export declare function createWorldChangeset(world: string, name: string, options?: WorldRootOptions & {
47
+ base?: string;
48
+ verifiers?: ChangesetVerifier[];
49
+ now?: Date;
50
+ overwrite?: boolean;
51
+ message?: string;
52
+ }): Changeset;
53
+ /** Every changeset in every world under `root` (or one world with `world`), newest first. */
54
+ export declare function listWorldChangesets(options?: WorldRootOptions & {
55
+ world?: string;
56
+ }): ChangesetLocation[];
57
+ /** Resolve a bare changeset name across worlds. Ambiguity is an error, never a guess. */
58
+ export declare function findWorldChangeset(name: string, options?: WorldRootOptions & {
59
+ world?: string;
60
+ }): ChangesetLocation;
61
+ /** Replay a changeset into `into`'s twins, through the control plane's kernel write path. */
62
+ export declare function replayWorldChangeset(name: string, options: WorldRootOptions & {
63
+ into: string;
64
+ world?: string;
65
+ }): Promise<ReplayReport>;
66
+ export type VerifyWorldOutcome = {
67
+ changeset: Changeset;
68
+ verification: ChangesetVerification;
69
+ report: ReplayReport;
70
+ world: string;
71
+ path: string;
72
+ };
73
+ /** The label a throwaway verify target reports as `into` — not a world name on purpose. */
74
+ export declare const EPHEMERAL_VERIFY_TARGET = "ephemeral";
75
+ /**
76
+ * `volter-world changeset verify <name> --into <world> | --ephemeral`: replay the changeset
77
+ * into a clean target, run its verifiers against the post-replay projected state, and record
78
+ * the outcome ON the object as `verification` — REPLACING any prior run (the record carries
79
+ * its own provenance: when, into what, against which body hash and world digest). The body
80
+ * hash never moves: verification is about-the-body metadata, like approvals.
81
+ *
82
+ * `--ephemeral` builds a throwaway replay target (fresh empty ledgers per twin, no world
83
+ * booted), verifies against it, and removes it — the zero-setup CI check. `--into` verifies
84
+ * inside an existing world, whose twins must cover the changeset AND its verifiers.
85
+ */
86
+ export declare function verifyWorldChangeset(name: string, options: WorldRootOptions & {
87
+ into?: string;
88
+ ephemeral?: boolean;
89
+ world?: string;
90
+ now?: Date;
91
+ }): Promise<VerifyWorldOutcome>;
92
+ export type ApproveWorldOutcome = {
93
+ changeset: Changeset;
94
+ approval: ChangesetApproval;
95
+ world: string;
96
+ path: string;
97
+ };
98
+ /** `volter-world changeset approve <name> --as <principal>`: append an approval bound to the
99
+ * current body hash. The control plane refuses a drifted object loudly. */
100
+ export declare function approveWorldChangeset(name: string, options: WorldRootOptions & {
101
+ principal: string;
102
+ note?: string;
103
+ world?: string;
104
+ now?: Date;
105
+ }): ApproveWorldOutcome;
106
+ /** `volter-world changeset status <name>`: the apply-readiness gate, recomputed from the
107
+ * object. Truth only — pushing is v2's job. */
108
+ export declare function statusWorldChangeset(name: string, options?: WorldRootOptions & {
109
+ world?: string;
110
+ }): ChangesetReadiness;
111
+ export type PushWorldOptions = WorldRootOptions & {
112
+ world?: string;
113
+ /** the remote's twins url and namespace; default to the world's recorded origin */
114
+ to?: string;
115
+ namespace?: string;
116
+ /** the namespace key (a push is a write; the read key is refused) */
117
+ key: string;
118
+ force?: boolean;
119
+ };
120
+ export type PushWorldOutcome = {
121
+ application: ChangesetApplication;
122
+ changeset: Changeset;
123
+ world: string;
124
+ path: string;
125
+ remote: {
126
+ url: string;
127
+ namespace: string;
128
+ }; /** the entries landed; these named records did not follow them (a warning, not a refusal) */
129
+ unsent?: string;
130
+ };
131
+ export declare function pushWorldChangeset(name: string, options: PushWorldOptions): Promise<PushWorldOutcome>;
132
+ export type RebaseWorldOutcome = {
133
+ changeset: Changeset;
134
+ report: RebaseReport;
135
+ world: string;
136
+ path: string;
137
+ };
138
+ /** `volter-world changeset rebase <name>`: the merge onto the authoring world's moved mirror. */
139
+ export declare function rebaseWorldChangeset(name: string, options?: WorldRootOptions & {
140
+ world?: string;
141
+ now?: Date;
142
+ }): RebaseWorldOutcome;