@astrale-os/sdk 0.6.0-beta.13 → 0.6.0-beta.15

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 (175) hide show
  1. package/README.md +4 -0
  2. package/dist/deployment/adapter/adapter.d.ts +9 -11
  3. package/dist/deployment/adapter/legacy/adapter.d.ts +0 -10
  4. package/dist/deployment/adapter/legacy/deploy/context.d.ts +0 -2
  5. package/dist/deployment/adapter/legacy/deploy/result.d.ts +2 -3
  6. package/dist/deployment/adapter/legacy/index.d.ts +12 -12
  7. package/dist/deployment/adapter/legacy/prepare/context.d.ts +0 -2
  8. package/dist/deployment/adapter/release/context.d.ts +23 -3
  9. package/dist/deployment/adapter/release/index.d.ts +1 -0
  10. package/dist/deployment/adapter/release/list.d.ts +41 -0
  11. package/dist/deployment/adapter/release/list.js +1 -0
  12. package/dist/deployment/address/index.d.ts +1 -1
  13. package/dist/deployment/address/index.js +1 -0
  14. package/dist/deployment/address/summary.d.ts +31 -1
  15. package/dist/deployment/address/summary.js +117 -1
  16. package/dist/deployment/build/index.d.ts +1 -1
  17. package/dist/deployment/build/index.js +1 -1
  18. package/dist/deployment/build/manifest.d.ts +5 -0
  19. package/dist/deployment/build/manifest.js +10 -0
  20. package/dist/deployment/index.d.ts +1 -1
  21. package/dist/deployment/release/legacy/index.d.ts +17 -12
  22. package/dist/deployment/release/legacy/index.js +17 -12
  23. package/dist/deployment/verify/readiness/deployment.js +3 -13
  24. package/dist/deployment/verify/readiness/fetch.d.ts +13 -0
  25. package/dist/deployment/verify/readiness/fetch.js +26 -0
  26. package/dist/deployment/verify/readiness/identity.d.ts +3 -6
  27. package/dist/deployment/verify/readiness/identity.js +3 -3
  28. package/dist/deployment/verify/readiness/index.d.ts +12 -8
  29. package/dist/deployment/verify/readiness/index.js +15 -4
  30. package/dist/deployment/verify/readiness/legacy/index.d.ts +2 -0
  31. package/dist/deployment/verify/readiness/legacy/index.js +2 -0
  32. package/dist/deployment/verify/readiness/legacy/publication.d.ts +12 -0
  33. package/dist/deployment/verify/readiness/legacy/publication.js +23 -0
  34. package/dist/deployment/verify/readiness/release.d.ts +8 -0
  35. package/dist/deployment/verify/readiness/release.js +22 -0
  36. package/dist/execution/identity/authentication.d.ts +14 -3
  37. package/dist/execution/identity/authentication.js +16 -7
  38. package/dist/execution/identity/callback.d.ts +5 -2
  39. package/dist/execution/identity/callback.js +11 -5
  40. package/dist/execution/identity/delivery.d.ts +11 -4
  41. package/dist/execution/identity/delivery.js +47 -20
  42. package/dist/execution/identity/identity.d.ts +12 -6
  43. package/dist/execution/identity/identity.js +3 -3
  44. package/dist/execution/invocation/admission/authentication.d.ts +1 -2
  45. package/dist/execution/invocation/admission/authentication.js +1 -2
  46. package/dist/execution/invocation/admission/authority.d.ts +10 -4
  47. package/dist/execution/invocation/admission/authority.js +5 -1
  48. package/dist/execution/invocation/invocation.js +51 -14
  49. package/dist/execution/runtime/index.d.ts +1 -0
  50. package/dist/execution/runtime/index.js +1 -0
  51. package/dist/execution/runtime/load.d.ts +3 -3
  52. package/dist/execution/runtime/load.js +3 -2
  53. package/dist/execution/runtime/release.d.ts +22 -0
  54. package/dist/execution/runtime/release.js +14 -0
  55. package/dist/execution/serve.d.ts +2 -2
  56. package/dist/execution/service/create.js +9 -7
  57. package/dist/execution/service/release.d.ts +2 -2
  58. package/dist/execution/service/release.js +3 -2
  59. package/dist/execution/service/service.d.ts +9 -5
  60. package/dist/execution/service/serving/delivery.d.ts +6 -0
  61. package/dist/execution/service/{publication → serving}/delivery.js +5 -1
  62. package/dist/execution/service/{publication → serving}/index.d.ts +1 -1
  63. package/dist/execution/service/serving/installation.d.ts +4 -0
  64. package/dist/execution/service/serving/installation.js +9 -0
  65. package/dist/execution/service/serving/legacy/index.d.ts +15 -0
  66. package/dist/execution/service/serving/legacy/index.js +19 -0
  67. package/dist/execution/service/serving/source.d.ts +18 -0
  68. package/dist/execution/service/serving/source.js +19 -0
  69. package/dist/execution/workflows/run.js +1 -1
  70. package/dist/platform/versioning/name.d.ts +4 -3
  71. package/dist/platform/versioning/name.js +4 -3
  72. package/dist/project/define.js +58 -28
  73. package/dist/project/install-command.d.ts +10 -0
  74. package/dist/project/install-command.js +13 -0
  75. package/dist/project/project.d.ts +4 -2
  76. package/dist/tooling/cli/arguments.d.ts +1 -3
  77. package/dist/tooling/cli/arguments.js +51 -22
  78. package/dist/tooling/cli/commit.d.ts +23 -0
  79. package/dist/tooling/cli/commit.js +216 -0
  80. package/dist/tooling/cli/deploy-mode.d.ts +16 -13
  81. package/dist/tooling/cli/deploy-mode.js +45 -36
  82. package/dist/tooling/cli/deploy-result.d.ts +10 -7
  83. package/dist/tooling/cli/deploy-result.js +4 -3
  84. package/dist/tooling/cli/dotenv.d.ts +2 -2
  85. package/dist/tooling/cli/dotenv.js +3 -33
  86. package/dist/tooling/cli/help.js +73 -29
  87. package/dist/tooling/cli/immutable-deployment.d.ts +27 -0
  88. package/dist/tooling/cli/immutable-deployment.js +95 -0
  89. package/dist/tooling/cli/index.d.ts +3 -4
  90. package/dist/tooling/cli/index.js +2 -3
  91. package/dist/tooling/cli/legacy/deploy-result.d.ts +5 -3
  92. package/dist/tooling/cli/legacy/deploy-result.js +5 -3
  93. package/dist/tooling/cli/{development → legacy/development}/candidate.d.ts +3 -4
  94. package/dist/tooling/cli/{development → legacy/development}/candidate.js +7 -14
  95. package/dist/tooling/cli/legacy/development/deployment.d.ts +10 -0
  96. package/dist/tooling/cli/legacy/development/deployment.js +20 -0
  97. package/dist/tooling/cli/legacy/development/deprecation.d.ts +11 -0
  98. package/dist/tooling/cli/legacy/development/deprecation.js +13 -0
  99. package/dist/tooling/cli/legacy/development/develop.d.ts +15 -0
  100. package/dist/tooling/cli/legacy/development/develop.js +142 -0
  101. package/dist/tooling/cli/legacy/development/index.d.ts +21 -0
  102. package/dist/tooling/cli/legacy/development/index.js +21 -0
  103. package/dist/tooling/cli/legacy/development/report.d.ts +7 -0
  104. package/dist/tooling/cli/{development → legacy/development}/report.js +2 -5
  105. package/dist/tooling/cli/legacy/development/secrets-file.d.ts +2 -0
  106. package/dist/tooling/cli/legacy/development/secrets-file.js +33 -0
  107. package/dist/tooling/cli/legacy/stable-target-adapter.d.ts +5 -3
  108. package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +40 -0
  109. package/dist/tooling/cli/legacy/stable-target-deploy.js +102 -0
  110. package/dist/tooling/cli/list.d.ts +114 -0
  111. package/dist/tooling/cli/list.js +297 -0
  112. package/dist/tooling/cli/orchestrate.d.ts +1 -1
  113. package/dist/tooling/cli/orchestrate.js +91 -95
  114. package/dist/tooling/cli/secrets.d.ts +9 -0
  115. package/dist/tooling/cli/secrets.js +19 -0
  116. package/package.json +7 -7
  117. package/dist/deployment/verify/readiness/publication.d.ts +0 -11
  118. package/dist/deployment/verify/readiness/publication.js +0 -41
  119. package/dist/execution/service/publication/delivery.d.ts +0 -2
  120. package/dist/execution/service/publication/installation.d.ts +0 -3
  121. package/dist/execution/service/publication/installation.js +0 -8
  122. package/dist/execution/service/publication/source.d.ts +0 -3
  123. package/dist/execution/service/publication/source.js +0 -11
  124. package/dist/tooling/cli/astrale/authority.d.ts +0 -5
  125. package/dist/tooling/cli/astrale/authority.js +0 -11
  126. package/dist/tooling/cli/astrale/executable.d.ts +0 -2
  127. package/dist/tooling/cli/astrale/executable.js +0 -47
  128. package/dist/tooling/cli/astrale/failure.d.ts +0 -6
  129. package/dist/tooling/cli/astrale/failure.js +0 -48
  130. package/dist/tooling/cli/astrale/instance.d.ts +0 -11
  131. package/dist/tooling/cli/astrale/instance.js +0 -52
  132. package/dist/tooling/cli/astrale/process.d.ts +0 -13
  133. package/dist/tooling/cli/astrale/process.js +0 -94
  134. package/dist/tooling/cli/astrale/version.d.ts +0 -18
  135. package/dist/tooling/cli/astrale/version.js +0 -55
  136. package/dist/tooling/cli/development/deployment.d.ts +0 -16
  137. package/dist/tooling/cli/development/deployment.js +0 -39
  138. package/dist/tooling/cli/development/develop.d.ts +0 -11
  139. package/dist/tooling/cli/development/develop.js +0 -243
  140. package/dist/tooling/cli/development/release-evidence.d.ts +0 -4
  141. package/dist/tooling/cli/development/release-evidence.js +0 -10
  142. package/dist/tooling/cli/development/report.d.ts +0 -9
  143. package/dist/tooling/cli/development/session-file.d.ts +0 -53
  144. package/dist/tooling/cli/development/session-file.js +0 -337
  145. package/dist/tooling/cli/development/target-lock.d.ts +0 -16
  146. package/dist/tooling/cli/development/target-lock.js +0 -68
  147. package/dist/tooling/cli/development/view.d.ts +0 -28
  148. package/dist/tooling/cli/development/view.js +0 -151
  149. package/dist/tooling/cli/environment-release.d.ts +0 -24
  150. package/dist/tooling/cli/environment-release.js +0 -46
  151. package/dist/tooling/cli/evidence.d.ts +0 -14
  152. package/dist/tooling/cli/evidence.js +0 -53
  153. package/dist/tooling/cli/installation/index.d.ts +0 -2
  154. package/dist/tooling/cli/installation/index.js +0 -1
  155. package/dist/tooling/cli/installation/observation.d.ts +0 -10
  156. package/dist/tooling/cli/installation/observation.js +0 -44
  157. package/dist/tooling/cli/installation/reconcile.d.ts +0 -32
  158. package/dist/tooling/cli/installation/reconcile.js +0 -122
  159. /package/dist/execution/service/{publication → serving}/index.js +0 -0
  160. /package/dist/tooling/cli/{credential.d.ts → legacy/development/credential.d.ts} +0 -0
  161. /package/dist/tooling/cli/{credential.js → legacy/development/credential.js} +0 -0
  162. /package/dist/tooling/cli/{development → legacy/development}/lease.d.ts +0 -0
  163. /package/dist/tooling/cli/{development → legacy/development}/lease.js +0 -0
  164. /package/dist/tooling/cli/{development → legacy/development}/lifecycle.d.ts +0 -0
  165. /package/dist/tooling/cli/{development → legacy/development}/lifecycle.js +0 -0
  166. /package/dist/tooling/cli/{development → legacy/development}/project-imports.d.ts +0 -0
  167. /package/dist/tooling/cli/{development → legacy/development}/project-imports.js +0 -0
  168. /package/dist/tooling/cli/{development → legacy/development}/project-lock.d.ts +0 -0
  169. /package/dist/tooling/cli/{development → legacy/development}/project-lock.js +0 -0
  170. /package/dist/tooling/cli/{development → legacy/development}/rebuild.d.ts +0 -0
  171. /package/dist/tooling/cli/{development → legacy/development}/rebuild.js +0 -0
  172. /package/dist/tooling/cli/{development → legacy/development}/source-watch.d.ts +0 -0
  173. /package/dist/tooling/cli/{development → legacy/development}/source-watch.js +0 -0
  174. /package/dist/tooling/cli/{development → legacy/development}/sources.d.ts +0 -0
  175. /package/dist/tooling/cli/{development → legacy/development}/sources.js +0 -0
@@ -0,0 +1,13 @@
1
+ export type ReadinessFetch = (input: string, init: {
2
+ readonly redirect: 'error';
3
+ readonly signal?: AbortSignal;
4
+ }) => Promise<Response>;
5
+ export interface ReadinessOptions {
6
+ readonly fetch?: ReadinessFetch;
7
+ readonly signal?: AbortSignal;
8
+ }
9
+ export declare const MAXIMUM_DOCUMENT_BYTES: number;
10
+ export declare const MAXIMUM_BUNDLE_BYTES: number;
11
+ export declare function fetchRequired(fetcher: ReadinessFetch, url: string, signal: AbortSignal | undefined): Promise<Response>;
12
+ export declare function bounded(response: Response, url: string, maximum: number): Promise<ArrayBuffer>;
13
+ export declare function text(response: Response, url: string, maximum: number): Promise<string>;
@@ -0,0 +1,26 @@
1
+ export const MAXIMUM_DOCUMENT_BYTES = 1024 * 1024;
2
+ export const MAXIMUM_BUNDLE_BYTES = 16 * 1024 * 1024;
3
+ export async function fetchRequired(fetcher, url, signal) {
4
+ const response = await fetcher(url, {
5
+ redirect: 'error',
6
+ ...(signal === undefined ? {} : { signal }),
7
+ });
8
+ if (!response.ok)
9
+ throw new Error(`GET ${url} returned ${response.status}.`);
10
+ return response;
11
+ }
12
+ export async function bounded(response, url, maximum) {
13
+ const bytes = await response.arrayBuffer();
14
+ if (bytes.byteLength > maximum)
15
+ throw new Error(`GET ${url} exceeded ${maximum} bytes.`);
16
+ return bytes;
17
+ }
18
+ export async function text(response, url, maximum) {
19
+ const bytes = await bounded(response, url, maximum);
20
+ try {
21
+ return new TextDecoder('utf-8', { fatal: true, ignoreBOM: false }).decode(bytes);
22
+ }
23
+ catch (cause) {
24
+ throw new Error(`GET ${url} returned invalid UTF-8.`, { cause });
25
+ }
26
+ }
@@ -1,7 +1,4 @@
1
- import type { Addressing } from '../../release/index.js';
2
- import type { ReadinessFetch } from './publication.js';
1
+ import type { IssuerId } from '../../../platform/auth/index.js';
2
+ import type { ReadinessOptions } from './fetch.js';
3
3
  /** Verify issuer discovery and at least one admitted signing key at the serving identity. */
4
- export declare function verifyIdentity(addressing: Addressing, options?: {
5
- readonly fetch?: ReadinessFetch;
6
- readonly signal?: AbortSignal;
7
- }): Promise<void>;
4
+ export declare function verifyIdentity(serving: IssuerId, options?: ReadinessOptions): Promise<void>;
@@ -1,10 +1,10 @@
1
1
  import { issuer } from '@astrale-os/kernel-protocol';
2
2
  const MAXIMUM_IDENTITY_BYTES = 256 * 1024;
3
3
  /** Verify issuer discovery and at least one admitted signing key at the serving identity. */
4
- export async function verifyIdentity(addressing, options = {}) {
4
+ export async function verifyIdentity(serving, options = {}) {
5
5
  const fetcher = options.fetch ?? globalThis.fetch;
6
- const configurationUrl = new URL(issuer.paths(addressing.issuer).configuration, addressing.issuer);
7
- const configuration = issuer.acceptConfiguration(await json(fetcher, configurationUrl.href, options.signal), addressing.issuer);
6
+ const configurationUrl = new URL(issuer.paths(serving).configuration, serving);
7
+ const configuration = issuer.acceptConfiguration(await json(fetcher, configurationUrl.href, options.signal), serving);
8
8
  const keys = issuer.acceptKeySet(await json(fetcher, configuration.jwks_uri, options.signal), configuration.id_token_signing_alg_values_supported);
9
9
  if (keys.keys.length === 0)
10
10
  throw new Error('Serving issuer publishes no signing keys.');
@@ -1,10 +1,14 @@
1
- import type { Release } from '../../release/legacy/index.js';
2
- import type { ReadinessFetch } from './publication.js';
1
+ import type { Release } from '../../release/index.js';
2
+ import type * as legacy from '../../release/legacy/index.js';
3
+ import type { ReadinessOptions } from './fetch.js';
3
4
  export { verifyDeployment } from './deployment.js';
4
5
  export { verifyIdentity } from './identity.js';
5
- export { verifyPublication, type ReadinessFetch } from './publication.js';
6
- /** Read-only verification of one exact live Release and serving identity. */
7
- export declare function readiness(release: Release, options?: {
8
- readonly fetch?: ReadinessFetch;
9
- readonly signal?: AbortSignal;
10
- }): Promise<void>;
6
+ export type { ReadinessFetch, ReadinessOptions } from './fetch.js';
7
+ export { verifyPublication } from './legacy/index.js';
8
+ export { verifyRelease } from './release.js';
9
+ /**
10
+ * Read-only verification of one exact live Release and its serving identity: an immutable
11
+ * deployment's `release.json` (release digest and build digest), or a stable target's
12
+ * `domain.json` (deprecated, `legacy/`).
13
+ */
14
+ export declare function readiness(release: Release | legacy.Release, options?: ReadinessOptions): Promise<void>;
@@ -1,10 +1,21 @@
1
1
  import { verifyIdentity } from './identity.js';
2
- import { verifyPublication } from './publication.js';
2
+ import { verifyPublication } from './legacy/index.js';
3
+ import { verifyRelease } from './release.js';
3
4
  export { verifyDeployment } from './deployment.js';
4
5
  export { verifyIdentity } from './identity.js';
5
- export { verifyPublication } from './publication.js';
6
- /** Read-only verification of one exact live Release and serving identity. */
6
+ export { verifyPublication } from './legacy/index.js';
7
+ export { verifyRelease } from './release.js';
8
+ /**
9
+ * Read-only verification of one exact live Release and its serving identity: an immutable
10
+ * deployment's `release.json` (release digest and build digest), or a stable target's
11
+ * `domain.json` (deprecated, `legacy/`).
12
+ */
7
13
  export async function readiness(release, options = {}) {
14
+ if (release.kind === 'release') {
15
+ await verifyRelease(release, options);
16
+ await verifyIdentity(release.url, options);
17
+ return;
18
+ }
8
19
  await verifyPublication(release, options);
9
- await verifyIdentity(release.addressing, options);
20
+ await verifyIdentity(release.addressing.issuer, options);
10
21
  }
@@ -0,0 +1,2 @@
1
+ /** @deprecated Stable-target readiness at `domain.json`; see `publication.ts` (removal D10). */
2
+ export { verifyPublication } from './publication.js';
@@ -0,0 +1,2 @@
1
+ /** @deprecated Stable-target readiness at `domain.json`; see `publication.ts` (removal D10). */
2
+ export { verifyPublication } from './publication.js';
@@ -0,0 +1,12 @@
1
+ import * as publication from '@astrale-os/kernel-protocol/release/legacy';
2
+ import type * as legacy from '../../../release/legacy/index.js';
3
+ import type { ReadinessOptions } from '../fetch.js';
4
+ /**
5
+ * Fetch and verify the exact live Publication and Bundle a stable target serves at `domain.json`.
6
+ *
7
+ * @deprecated Replacement: `verifyRelease`, the readiness of an immutable deployment at
8
+ * `release.json` (release digest and build digest). Consumer: the direct-mode deploy path of
9
+ * adapter-cloudflare (the consumers of `deployment/release/legacy/index.ts`).
10
+ * Removal: D10, with that path.
11
+ */
12
+ export declare function verifyPublication(release: legacy.Release, options?: ReadinessOptions): Promise<publication.Publication>;
@@ -0,0 +1,23 @@
1
+ import * as publication from '@astrale-os/kernel-protocol/release/legacy';
2
+ import { bounded, fetchRequired, MAXIMUM_BUNDLE_BYTES, MAXIMUM_DOCUMENT_BYTES, text, } from '../fetch.js';
3
+ /**
4
+ * Fetch and verify the exact live Publication and Bundle a stable target serves at `domain.json`.
5
+ *
6
+ * @deprecated Replacement: `verifyRelease`, the readiness of an immutable deployment at
7
+ * `release.json` (release digest and build digest). Consumer: the direct-mode deploy path of
8
+ * adapter-cloudflare (the consumers of `deployment/release/legacy/index.ts`).
9
+ * Removal: D10, with that path.
10
+ */
11
+ export async function verifyPublication(release, options = {}) {
12
+ const fetcher = options.fetch ?? globalThis.fetch;
13
+ const publicationUrl = publication.url(release.addressing.publicUrl);
14
+ const response = await fetchRequired(fetcher, publicationUrl, options.signal);
15
+ const deployed = publication.accept(JSON.parse(await text(response, publicationUrl, MAXIMUM_DOCUMENT_BYTES)));
16
+ if (!publication.matchesReference(deployed, publication.reference(release.publication))) {
17
+ throw new Error('Live Publication differs from the expected Release.');
18
+ }
19
+ const bundleResponse = await fetchRequired(fetcher, deployed.schema.bundle.href, options.signal);
20
+ const bytes = new Uint8Array(await bounded(bundleResponse, deployed.schema.bundle.href, MAXIMUM_BUNDLE_BYTES));
21
+ publication.decodeBundle(deployed, bytes);
22
+ return deployed;
23
+ }
@@ -0,0 +1,8 @@
1
+ import * as release from '@astrale-os/kernel-protocol/release';
2
+ import type { Release } from '../../release/index.js';
3
+ import type { ReadinessOptions } from './fetch.js';
4
+ /**
5
+ * Fetch and verify the exact live release of one immutable deployment at its `release.json`: its
6
+ * release digest and the build digest of its code, then its Bundle.
7
+ */
8
+ export declare function verifyRelease(expected: Release, options?: ReadinessOptions): Promise<release.DomainRelease>;
@@ -0,0 +1,22 @@
1
+ import * as release from '@astrale-os/kernel-protocol/release';
2
+ import { bounded, fetchRequired, MAXIMUM_BUNDLE_BYTES, MAXIMUM_DOCUMENT_BYTES, text, } from './fetch.js';
3
+ /**
4
+ * Fetch and verify the exact live release of one immutable deployment at its `release.json`: its
5
+ * release digest and the build digest of its code, then its Bundle.
6
+ */
7
+ export async function verifyRelease(expected, options = {}) {
8
+ const fetcher = options.fetch ?? globalThis.fetch;
9
+ const releaseUrl = release.url(expected.url);
10
+ const response = await fetchRequired(fetcher, releaseUrl, options.signal);
11
+ const deployed = release.accept(JSON.parse(await text(response, releaseUrl, MAXIMUM_DOCUMENT_BYTES)));
12
+ if (!release.matchesReference(deployed, release.reference(expected.document))) {
13
+ throw new Error('Live release differs from the expected Release.');
14
+ }
15
+ if (deployed.build.digest !== expected.buildDigest) {
16
+ throw new Error('Live release build digest differs from the expected build.');
17
+ }
18
+ const bundleResponse = await fetchRequired(fetcher, deployed.schema.bundle.href, options.signal);
19
+ const bytes = new Uint8Array(await bounded(bundleResponse, deployed.schema.bundle.href, MAXIMUM_BUNDLE_BYTES));
20
+ release.decodeBundle(deployed, bytes);
21
+ return deployed;
22
+ }
@@ -5,6 +5,14 @@ import type { InvocationAdmissionInput } from '../invocation/index.js';
5
5
  import type { IdentityNetworkPolicy, VerificationBasis, VerificationBasisResolver } from './jwks.js';
6
6
  import type { SigningMaterial } from './signing.js';
7
7
  import { ClientSession } from '../../platform/client/session/index.js';
8
+ import { NodeId } from '../../platform/graph/node/index.js';
9
+ /**
10
+ * How long a callback Session reuses a learned route. It stays at most the Kernel's in-flight
11
+ * issuer window (`KERNEL_INFLIGHT_ISSUER_MS`, Host default 300 s; CT11): a route learned to a
12
+ * deployment replaced by a consented install ages out while that deployment is still accepted and
13
+ * answers the reserved miss, never after its own credential is refused (AM-85).
14
+ */
15
+ export declare const DEFAULT_ROUTE_AGE_MS = 60000;
8
16
  export declare function admit(request: InvocationAdmissionInput, configuration: AuthenticationConfiguration): Promise<unknown>;
9
17
  export interface AuthenticationConfiguration {
10
18
  readonly issuer: IssuerId;
@@ -19,10 +27,13 @@ export declare function authenticate(credentialInput: CredentialInput, expectedK
19
27
  readonly signal: AbortSignal;
20
28
  }, configuration: AuthenticationConfiguration): Promise<AuthenticatedInvocation>;
21
29
  /**
22
- * The Domain's own authority toward one Kernel, for work no caller credential carries: a durable
23
- * run acts as its executor, never as its initiator. The caller owns the returned Session.
30
+ * The Domain's own authority toward one Kernel for a step of the durable Execution `executionId`,
31
+ * which no caller credential carries: the run acts as its executor, never as its initiator. Every
32
+ * credential names `executionId` in `EXECUTION_CLAIM`, so the Kernel can accept a replaced issuer
33
+ * for the steps of a run in flight at a consented issuer change. The caller owns the returned
34
+ * Session.
24
35
  */
25
- export declare function executorSession(kernel: IssuerId, execution: {
36
+ export declare function executorSession(kernel: IssuerId, executionId: NodeId, execution: {
26
37
  readonly deadline: number;
27
38
  readonly signal: AbortSignal;
28
39
  }, configuration: AuthenticationConfiguration): ClientSession;
@@ -10,7 +10,13 @@ import { projectError, protocolError } from '../invocation/result/index.js';
10
10
  import { callbackIdentities, createCallbackCredentialResolver, maximumCallbackDelegationTtlSeconds, selfIdentity, signDomainCallback, } from './callback.js';
11
11
  import { CredentialRejected, IssuerUnavailable, boundedFetch, callbackTtl, httpIssuer, invocationUrl, admitEndpoint, requireLive, } from './errors.js';
12
12
  import { verifyCredential, verifyCredentialAgainst } from './jwks.js';
13
- const DEFAULT_ROUTE_AGE_MS = 60_000;
13
+ /**
14
+ * How long a callback Session reuses a learned route. It stays at most the Kernel's in-flight
15
+ * issuer window (`KERNEL_INFLIGHT_ISSUER_MS`, Host default 300 s; CT11): a route learned to a
16
+ * deployment replaced by a consented install ages out while that deployment is still accepted and
17
+ * answers the reserved miss, never after its own credential is refused (AM-85).
18
+ */
19
+ export const DEFAULT_ROUTE_AGE_MS = 60_000;
14
20
  export async function admit(request, configuration) {
15
21
  const execution = request.context.execution;
16
22
  requireLive(execution);
@@ -73,16 +79,19 @@ export async function authenticate(credentialInput, expectedKernel, execution, c
73
79
  });
74
80
  }
75
81
  /**
76
- * The Domain's own authority toward one Kernel, for work no caller credential carries: a durable
77
- * run acts as its executor, never as its initiator. The caller owns the returned Session.
82
+ * The Domain's own authority toward one Kernel for a step of the durable Execution `executionId`,
83
+ * which no caller credential carries: the run acts as its executor, never as its initiator. Every
84
+ * credential names `executionId` in `EXECUTION_CLAIM`, so the Kernel can accept a replaced issuer
85
+ * for the steps of a run in flight at a consented issuer change. The caller owns the returned
86
+ * Session.
78
87
  */
79
- export function executorSession(kernel, execution, configuration) {
88
+ export function executorSession(kernel, executionId, execution, configuration) {
80
89
  const admitted = httpIssuer(kernel, configuration.policy.allowInsecureHttp === true);
81
90
  admitEndpoint(invocationUrl(admitted), configuration.policy);
82
- return callbackSession(admitted, selfIdentity, undefined, execution, configuration);
91
+ return callbackSession(admitted, selfIdentity, undefined, execution, configuration, executionId);
83
92
  }
84
- function callbackSession(kernel, expression, carrier, execution, configuration) {
85
- const resolveCallback = createCallbackCredentialResolver(configuration.signing, configuration.issuer, configuration.subject, kernel, expression, carrier, execution);
93
+ function callbackSession(kernel, expression, carrier, execution, configuration, executionId) {
94
+ const resolveCallback = createCallbackCredentialResolver(configuration.signing, configuration.issuer, configuration.subject, kernel, expression, carrier, execution, executionId);
86
95
  return new ClientSession({
87
96
  kernel,
88
97
  fetch: boundedFetch(configuration.fetch, execution.signal),
@@ -1,4 +1,5 @@
1
1
  import type { IssuerId, UnresolvedIdentityExpr, VerifiedCredential } from '../../platform/auth/index.js';
2
+ import type { NodeId } from '../../platform/graph/node/index.js';
2
3
  import type { SigningMaterial } from './signing.js';
3
4
  export declare const maximumCallbackTtlSeconds = 120;
4
5
  export declare const maximumCallbackDelegationTtlSeconds = 60;
@@ -34,9 +35,11 @@ export declare function signCallback(signing: SigningMaterial, issuer: IssuerId,
34
35
  }): Promise<string>;
35
36
  /**
36
37
  * Reuse one exact callback authority partition, refreshing only near its bounded expiry. Without a
37
- * carrier the callback is the Domain's own authority, bounded by the execution alone.
38
+ * carrier the callback is the Domain's own authority, bounded by the execution alone. An
39
+ * `executionId` is the durable Execution a step's executor credential names in `EXECUTION_CLAIM`;
40
+ * no caller-bound callback names one.
38
41
  */
39
42
  export declare function createCallbackCredentialResolver(signing: SigningMaterial, issuer: IssuerId, subject: string, audience: IssuerId, expression: UnresolvedIdentityExpr, carrier: VerifiedCredential | undefined, execution: {
40
43
  readonly deadline: number;
41
44
  readonly signal: AbortSignal;
42
- }): (signal: AbortSignal) => Promise<SignedCallback>;
45
+ }, executionId?: NodeId): (signal: AbortSignal) => Promise<SignedCallback>;
@@ -1,3 +1,4 @@
1
+ import { EXECUTION_CLAIM } from '@astrale-os/kernel-protocol/issuer/claims';
1
2
  import { SignJWT } from 'jose';
2
3
  import { protocolError } from '../invocation/result/index.js';
3
4
  import { requireLive } from './errors.js';
@@ -22,9 +23,11 @@ export async function signCallback(signing, issuer, subject, audience, expressio
22
23
  }
23
24
  /**
24
25
  * Reuse one exact callback authority partition, refreshing only near its bounded expiry. Without a
25
- * carrier the callback is the Domain's own authority, bounded by the execution alone.
26
+ * carrier the callback is the Domain's own authority, bounded by the execution alone. An
27
+ * `executionId` is the durable Execution a step's executor credential names in `EXECUTION_CLAIM`;
28
+ * no caller-bound callback names one.
26
29
  */
27
- export function createCallbackCredentialResolver(signing, issuer, subject, audience, expression, carrier, execution) {
30
+ export function createCallbackCredentialResolver(signing, issuer, subject, audience, expression, carrier, execution, executionId) {
28
31
  const maximum = carrier?.exp ?? Number.POSITIVE_INFINITY;
29
32
  let cached;
30
33
  let pending;
@@ -37,7 +40,7 @@ export function createCallbackCredentialResolver(signing, issuer, subject, audie
37
40
  return cached;
38
41
  }
39
42
  if (pending === undefined) {
40
- const current = sign(signing, issuer, subject, audience, expression, execution, maximum).then((signed) => {
43
+ const current = sign(signing, issuer, subject, audience, expression, execution, maximum, executionId).then((signed) => {
41
44
  const delegateTtlSeconds = Math.min(maximumCallbackDelegationTtlSeconds, signed.expiresAt - signed.issuedAt - CALLBACK_DELEGATION_SKEW_SECONDS);
42
45
  if (delegateTtlSeconds < 1) {
43
46
  throw protocolError('AUTH_INVALID', 'Credential is invalid.');
@@ -60,7 +63,7 @@ export function createCallbackCredentialResolver(signing, issuer, subject, audie
60
63
  return withSignal(pending, signal);
61
64
  };
62
65
  }
63
- async function sign(signing, issuer, subject, audience, expression, execution, maximum = Number.POSITIVE_INFINITY) {
66
+ async function sign(signing, issuer, subject, audience, expression, execution, maximum = Number.POSITIVE_INFINITY, executionId) {
64
67
  requireLive(execution);
65
68
  const privateKey = await withSignal(signing.privateKey, execution.signal);
66
69
  requireLive(execution);
@@ -69,7 +72,10 @@ async function sign(signing, issuer, subject, audience, expression, execution, m
69
72
  if (!Number.isFinite(expiresAt) || expiresAt <= now) {
70
73
  throw protocolError('AUTH_INVALID', 'Credential is invalid.');
71
74
  }
72
- const credential = await withSignal(new SignJWT({ grant: { v: 1, expr: expression } })
75
+ const credential = await withSignal(new SignJWT({
76
+ grant: { v: 1, expr: expression },
77
+ ...(executionId === undefined ? {} : { [EXECUTION_CLAIM]: executionId }),
78
+ })
73
79
  .setProtectedHeader({
74
80
  alg: signing.algorithm,
75
81
  ...(signing.keyId === undefined ? {} : { kid: signing.keyId }),
@@ -1,6 +1,13 @@
1
- import type { publication as serverPublication } from '@astrale-os/kernel-server';
2
- import * as publication from '@astrale-os/kernel-protocol/release/legacy';
1
+ import type { release as serverRelease } from '@astrale-os/kernel-server';
2
+ import * as release from '@astrale-os/kernel-protocol/release';
3
3
  import type { IssuerId } from '../../platform/auth/index.js';
4
4
  import type { SigningMaterial } from './signing.js';
5
- /** Create one stateless, nonce-bound public Delivery provider for an exact Publication. */
6
- export declare function publicationDelivery(signing: SigningMaterial, issuer: IssuerId, subject: string, deployed: publication.Publication): serverPublication.delivery.Provider;
5
+ type Served = release.DomainRelease | release.legacy.Publication;
6
+ /**
7
+ * Create one stateless, nonce-bound public Delivery provider for the exact document a deployment
8
+ * serves. It answers in the request's version: a Delivery v2 carrying the release for a v2
9
+ * request, and a Delivery v1 carrying the Publication (a release's frozen v3 projection) for the
10
+ * deprecated v1 request. A stable target's Publication answers v1 only.
11
+ */
12
+ export declare function releaseDelivery(signing: SigningMaterial, issuer: IssuerId, subject: string, deployed: Served): serverRelease.delivery.Provider;
13
+ export {};
@@ -1,34 +1,61 @@
1
- import * as publication from '@astrale-os/kernel-protocol/release/legacy';
1
+ import * as release from '@astrale-os/kernel-protocol/release';
2
2
  import { SignJWT } from 'jose';
3
3
  const ATTESTATION_TTL_SECONDS = 60;
4
- /** Create one stateless, nonce-bound public Delivery provider for an exact Publication. */
5
- export function publicationDelivery(signing, issuer, subject, deployed) {
4
+ /**
5
+ * Create one stateless, nonce-bound public Delivery provider for the exact document a deployment
6
+ * serves. It answers in the request's version: a Delivery v2 carrying the release for a v2
7
+ * request, and a Delivery v1 carrying the Publication (a release's frozen v3 projection) for the
8
+ * deprecated v1 request. A stable target's Publication answers v1 only.
9
+ */
10
+ export function releaseDelivery(signing, issuer, subject, deployed) {
11
+ const projection = deployed.version === 4 ? release.legacy.publication(deployed) : deployed;
6
12
  return Object.freeze({
7
13
  async create(request, context) {
8
14
  context.signal.throwIfAborted();
9
- const now = Math.floor(Date.now() / 1_000);
10
- const attestation = await new SignJWT({
11
- purpose: publication.delivery.PURPOSE,
15
+ if (request.version === 1) {
16
+ const attestation = await attest(signing, issuer, subject, request.kernel, {
17
+ purpose: release.legacy.delivery.PURPOSE,
18
+ nonce: request.nonce,
19
+ etag: projection.etag,
20
+ schemaRevision: projection.schema.revision,
21
+ });
22
+ context.signal.throwIfAborted();
23
+ return release.legacy.delivery.accept({
24
+ format: 'astrale.domain.delivery',
25
+ version: 1,
26
+ publication: projection,
27
+ attestation,
28
+ });
29
+ }
30
+ if (deployed.version !== 4) {
31
+ throw new TypeError('A Publication-backed deployment answers Delivery v1 only.');
32
+ }
33
+ const attestation = await attest(signing, issuer, subject, request.kernel, {
34
+ purpose: release.delivery.PURPOSE,
12
35
  nonce: request.nonce,
13
- etag: deployed.etag,
36
+ release: deployed.digest,
14
37
  schemaRevision: deployed.schema.revision,
15
- })
16
- .setProtectedHeader({
17
- alg: signing.algorithm,
18
- ...(signing.keyId === undefined ? {} : { kid: signing.keyId }),
19
- })
20
- .setIssuer(issuer)
21
- .setSubject(subject)
22
- .setAudience(request.kernel)
23
- .setExpirationTime(now + ATTESTATION_TTL_SECONDS)
24
- .sign(await signing.privateKey);
38
+ });
25
39
  context.signal.throwIfAborted();
26
- return publication.delivery.accept({
40
+ return release.delivery.accept({
27
41
  format: 'astrale.domain.delivery',
28
- version: 1,
29
- publication: deployed,
42
+ version: 2,
43
+ release: deployed,
30
44
  attestation,
31
45
  });
32
46
  },
33
47
  });
34
48
  }
49
+ async function attest(signing, issuer, subject, kernel, claims) {
50
+ const now = Math.floor(Date.now() / 1_000);
51
+ return new SignJWT(claims)
52
+ .setProtectedHeader({
53
+ alg: signing.algorithm,
54
+ ...(signing.keyId === undefined ? {} : { kid: signing.keyId }),
55
+ })
56
+ .setIssuer(issuer)
57
+ .setSubject(subject)
58
+ .setAudience(kernel)
59
+ .setExpirationTime(now + ATTESTATION_TTL_SECONDS)
60
+ .sign(await signing.privateKey);
61
+ }
@@ -1,8 +1,9 @@
1
1
  import type { Fetch } from '@astrale-os/kernel-client';
2
- import type * as publicationProtocol from '@astrale-os/kernel-protocol/release/legacy';
3
- import type { Issuer, exchange, publication } from '@astrale-os/kernel-server';
2
+ import type * as releaseProtocol from '@astrale-os/kernel-protocol/release';
3
+ import type { Issuer, exchange, release } from '@astrale-os/kernel-server';
4
4
  import type { IssuerId, JsonWebKey } from '../../platform/auth/index.js';
5
5
  import type { ClientSession } from '../../platform/client/session/index.js';
6
+ import type { NodeId } from '../../platform/graph/node/index.js';
6
7
  import type { InvocationAuthority } from '../invocation/index.js';
7
8
  import type { ExchangeOptions } from './exchange.js';
8
9
  import type { IdentityNetworkPolicy } from './jwks.js';
@@ -10,12 +11,17 @@ import type { IdentityNetworkPolicy } from './jwks.js';
10
11
  export interface Identity extends Issuer, InvocationAuthority {
11
12
  readonly subject: string;
12
13
  readonly tokenExchange?: exchange.Provider;
13
- delivery(publication: publicationProtocol.Publication): publication.delivery.Provider;
14
14
  /**
15
- * The Domain's own authority toward one Kernel for work no caller credential carries, such as a
16
- * durable run. Required to serve durable Workflows; the caller closes the Session.
15
+ * Delivery for the exact document this deployment serves: Delivery v2 over its release and v1
16
+ * over its frozen v3 projection, or v1 over a stable target's Publication.
17
17
  */
18
- executor?(kernel: IssuerId, execution: {
18
+ delivery(served: releaseProtocol.DomainRelease | releaseProtocol.legacy.Publication): release.delivery.Provider;
19
+ /**
20
+ * The Domain's own authority toward one Kernel for a step of the durable Execution `executionId`
21
+ * (`ctx.execution.id`), which no caller credential carries; its credentials name `executionId` in
22
+ * `EXECUTION_CLAIM`. Required to serve durable Workflows; the caller closes the Session.
23
+ */
24
+ executor?(kernel: IssuerId, executionId: NodeId, execution: {
19
25
  readonly deadline: number;
20
26
  readonly signal: AbortSignal;
21
27
  }): ClientSession;
@@ -1,5 +1,5 @@
1
1
  import { admit, authenticate, executorSession } from './authentication.js';
2
- import { publicationDelivery } from './delivery.js';
2
+ import { releaseDelivery } from './delivery.js';
3
3
  import { httpIssuer } from './errors.js';
4
4
  import { maximumExchangeTtl, tokenExchange } from './exchange.js';
5
5
  import { createVerificationBasisResolver } from './jwks.js';
@@ -49,9 +49,9 @@ export function createIdentity(input) {
49
49
  ? {}
50
50
  : { loadIssuerPublicKeys: input.loadIssuerPublicKeys }),
51
51
  ...(exchangeProvider === undefined ? {} : { tokenExchange: exchangeProvider }),
52
- delivery: (publication) => publicationDelivery(material, issuer, input.subject, publication),
52
+ delivery: (served) => releaseDelivery(material, issuer, input.subject, served),
53
53
  admit: (request) => admit(request, configuration),
54
- executor: (kernel, execution) => executorSession(kernel, execution, configuration),
54
+ executor: (kernel, executionId, execution) => executorSession(kernel, executionId, execution, configuration),
55
55
  authenticate: (request) => authenticate(request.credential, request.via.issuer, request.context.execution, configuration),
56
56
  });
57
57
  }
@@ -1,6 +1,5 @@
1
1
  import type { HandlerRequest } from '@astrale-os/kernel-server';
2
2
  import type { AnonymousCaller, ResolvedCallable } from '../../../application/action/index.js';
3
- import type { Release } from '../../../deployment/release/legacy/index.js';
4
3
  import type { Domain } from '../../../platform/schema/index.js';
5
4
  import type { AuthenticatedInvocation, InvocationAuthority } from './authority.js';
6
5
  export interface AnonymousInvocation {
@@ -10,4 +9,4 @@ export interface AnonymousInvocation {
10
9
  close(): void;
11
10
  }
12
11
  export type InvocationAuthentication = AnonymousInvocation | AuthenticatedInvocation;
13
- export declare function authentication(callable: ResolvedCallable, request: HandlerRequest, release: Release, domain: Domain, authority: InvocationAuthority): Promise<InvocationAuthentication>;
12
+ export declare function authentication(callable: ResolvedCallable, request: HandlerRequest, domain: Domain, authority: InvocationAuthority): Promise<InvocationAuthentication>;
@@ -9,7 +9,7 @@ const ANONYMOUS = Object.freeze({
9
9
  graph: null,
10
10
  close() { },
11
11
  });
12
- export async function authentication(callable, request, release, domain, authority) {
12
+ export async function authentication(callable, request, domain, authority) {
13
13
  const credential = request.credential;
14
14
  if (callable.auth === 'anonymous' && credential === undefined)
15
15
  return ANONYMOUS;
@@ -21,7 +21,6 @@ export async function authentication(callable, request, release, domain, authori
21
21
  const authenticated = await authority.authenticate({
22
22
  credential,
23
23
  via: requireVia(request),
24
- publication: release.publication,
25
24
  domain,
26
25
  context: request.context,
27
26
  });
@@ -1,5 +1,4 @@
1
1
  import type * as invocation from '@astrale-os/kernel-protocol/invocation';
2
- import type * as publication from '@astrale-os/kernel-protocol/release/legacy';
3
2
  import type { HandlerRequest, InvocationContext } from '@astrale-os/kernel-server';
4
3
  import type { AuthenticatedCaller } from '../../../application/action/index.js';
5
4
  import type { BoundClientSession } from '../../../platform/client/session/index.js';
@@ -8,14 +7,12 @@ export interface InvocationAdmissionInput {
8
7
  readonly call: invocation.Call;
9
8
  readonly credential?: string;
10
9
  readonly via: invocation.Via | invocation.PublicationVia;
11
- readonly publication: publication.Publication;
12
10
  readonly domain: Domain;
13
11
  readonly context: InvocationContext;
14
12
  }
15
13
  export interface InvocationAuthenticationInput {
16
14
  readonly credential: string;
17
15
  readonly via: invocation.Via | invocation.PublicationVia;
18
- readonly publication: publication.Publication;
19
16
  readonly domain: Domain;
20
17
  readonly context: InvocationContext;
21
18
  }
@@ -26,10 +23,19 @@ export interface AuthenticatedInvocation {
26
23
  close(): void;
27
24
  }
28
25
  export interface InvocationAuthority {
26
+ /**
27
+ * The source Kernel's `Function.admit` of a remote call: resolves to the admitted target, or
28
+ * rejects with the public refusal. A refusal whose reason is `FUNCTION_MISS` (the Kernel no longer
29
+ * places the call on this deployment) is answered as the reserved miss, never as an error.
30
+ */
29
31
  admit(input: InvocationAdmissionInput): Promise<unknown>;
30
32
  authenticate(input: InvocationAuthenticationInput): Promise<AuthenticatedInvocation>;
31
33
  }
32
34
  /** Capture the execution Identity capability and receiver-bind both privileged operations. */
33
35
  export declare function authority(input: InvocationAuthority): InvocationAuthority;
34
- /** The routed witness of a remote call: a `ReleaseRef`, or the `PublicationRef` of a v3 pin. */
36
+ /**
37
+ * The routed witness of a remote call, already admitted by the Kernel Server against the served
38
+ * snapshot: the exact `ReleaseRef` of an immutable deployment, or the `PublicationRef` of a v3 pin
39
+ * (a release's exact projection, or a stable target's Publication).
40
+ */
35
41
  export declare function requireVia(request: HandlerRequest): invocation.Via | invocation.PublicationVia;
@@ -12,7 +12,11 @@ export function authority(input) {
12
12
  authenticate: receiver.authenticate.bind(receiver),
13
13
  });
14
14
  }
15
- /** The routed witness of a remote call: a `ReleaseRef`, or the `PublicationRef` of a v3 pin. */
15
+ /**
16
+ * The routed witness of a remote call, already admitted by the Kernel Server against the served
17
+ * snapshot: the exact `ReleaseRef` of an immutable deployment, or the `PublicationRef` of a v3 pin
18
+ * (a release's exact projection, or a stable target's Publication).
19
+ */
16
20
  export function requireVia(request) {
17
21
  if (request.via === undefined) {
18
22
  throw protocolError('VALIDATION_ERROR', 'Remote invocation requires Via.');