@astrale-os/sdk 0.6.0-beta.14 → 0.6.0-beta.16

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 (98) hide show
  1. package/dist/deployment/adapter/adapter.d.ts +11 -7
  2. package/dist/deployment/adapter/index.d.ts +1 -0
  3. package/dist/deployment/adapter/index.js +1 -0
  4. package/dist/deployment/adapter/legacy/index.d.ts +6 -8
  5. package/dist/deployment/adapter/release/context.d.ts +7 -1
  6. package/dist/deployment/adapter/release/index.d.ts +1 -0
  7. package/dist/deployment/adapter/release/list.d.ts +41 -0
  8. package/dist/deployment/adapter/release/list.js +1 -0
  9. package/dist/deployment/adapter/release/refusal.d.ts +10 -0
  10. package/dist/deployment/adapter/release/refusal.js +14 -0
  11. package/dist/deployment/address/summary.d.ts +1 -1
  12. package/dist/deployment/index.d.ts +1 -1
  13. package/dist/deployment/release/legacy/index.d.ts +2 -2
  14. package/dist/deployment/release/legacy/index.js +2 -2
  15. package/dist/deployment/verify/readiness/legacy/publication.d.ts +1 -1
  16. package/dist/deployment/verify/readiness/legacy/publication.js +1 -1
  17. package/dist/execution/identity/authentication.d.ts +7 -3
  18. package/dist/execution/identity/authentication.js +9 -6
  19. package/dist/execution/identity/callback.d.ts +5 -2
  20. package/dist/execution/identity/callback.js +11 -5
  21. package/dist/execution/identity/identity.d.ts +5 -3
  22. package/dist/execution/identity/identity.js +1 -1
  23. package/dist/execution/workflows/run.js +1 -1
  24. package/dist/platform/versioning/name.d.ts +4 -3
  25. package/dist/platform/versioning/name.js +4 -3
  26. package/dist/project/define.js +12 -11
  27. package/dist/tooling/cli/arguments.d.ts +7 -1
  28. package/dist/tooling/cli/arguments.js +94 -10
  29. package/dist/tooling/cli/commit.d.ts +12 -0
  30. package/dist/tooling/cli/commit.js +19 -0
  31. package/dist/tooling/cli/deploy-mode.d.ts +25 -17
  32. package/dist/tooling/cli/deploy-mode.js +66 -12
  33. package/dist/tooling/cli/diff/declared.d.ts +7 -0
  34. package/dist/tooling/cli/diff/declared.js +27 -0
  35. package/dist/tooling/cli/diff/index.d.ts +30 -0
  36. package/dist/tooling/cli/diff/index.js +58 -0
  37. package/dist/tooling/cli/diff/render.d.ts +15 -0
  38. package/dist/tooling/cli/diff/render.js +131 -0
  39. package/dist/tooling/cli/diff/report.d.ts +88 -0
  40. package/dist/tooling/cli/diff/report.js +154 -0
  41. package/dist/tooling/cli/dotenv.d.ts +2 -2
  42. package/dist/tooling/cli/dotenv.js +3 -33
  43. package/dist/tooling/cli/help.js +148 -8
  44. package/dist/tooling/cli/immutable-deployment.d.ts +65 -9
  45. package/dist/tooling/cli/immutable-deployment.js +59 -19
  46. package/dist/tooling/cli/index.d.ts +9 -2
  47. package/dist/tooling/cli/index.js +6 -2
  48. package/dist/tooling/cli/{development → legacy/development}/candidate.d.ts +2 -2
  49. package/dist/tooling/cli/{development → legacy/development}/candidate.js +5 -5
  50. package/dist/tooling/cli/{development → legacy/development}/deployment.d.ts +1 -1
  51. package/dist/tooling/cli/{development → legacy/development}/deployment.js +1 -1
  52. package/dist/tooling/cli/legacy/development/deprecation.d.ts +11 -0
  53. package/dist/tooling/cli/legacy/development/deprecation.js +13 -0
  54. package/dist/tooling/cli/{development → legacy/development}/develop.d.ts +3 -0
  55. package/dist/tooling/cli/{development → legacy/development}/develop.js +7 -4
  56. package/dist/tooling/cli/legacy/development/index.d.ts +21 -0
  57. package/dist/tooling/cli/legacy/development/index.js +21 -0
  58. package/dist/tooling/cli/{development → legacy/development}/report.d.ts +1 -1
  59. package/dist/tooling/cli/{development → legacy/development}/report.js +1 -1
  60. package/dist/tooling/cli/legacy/development/secrets-file.d.ts +2 -0
  61. package/dist/tooling/cli/legacy/development/secrets-file.js +33 -0
  62. package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +3 -5
  63. package/dist/tooling/cli/legacy/stable-target-deploy.js +3 -5
  64. package/dist/tooling/cli/list.d.ts +114 -0
  65. package/dist/tooling/cli/list.js +297 -0
  66. package/dist/tooling/cli/orchestrate.d.ts +1 -1
  67. package/dist/tooling/cli/orchestrate.js +153 -4
  68. package/dist/tooling/cli/publish/index.d.ts +74 -0
  69. package/dist/tooling/cli/publish/index.js +364 -0
  70. package/dist/tooling/cli/publish/report.d.ts +49 -0
  71. package/dist/tooling/cli/publish/report.js +15 -0
  72. package/dist/tooling/cli/registry/client.d.ts +127 -0
  73. package/dist/tooling/cli/registry/client.js +328 -0
  74. package/dist/tooling/cli/registry/executable.d.ts +20 -0
  75. package/dist/tooling/cli/registry/executable.js +79 -0
  76. package/dist/tooling/cli/registry/index.d.ts +6 -0
  77. package/dist/tooling/cli/registry/index.js +6 -0
  78. package/dist/tooling/cli/registry/process.d.ts +21 -0
  79. package/dist/tooling/cli/registry/process.js +84 -0
  80. package/dist/tooling/cli/yank.d.ts +34 -0
  81. package/dist/tooling/cli/yank.js +32 -0
  82. package/package.json +8 -8
  83. /package/dist/tooling/cli/{credential.d.ts → legacy/development/credential.d.ts} +0 -0
  84. /package/dist/tooling/cli/{credential.js → legacy/development/credential.js} +0 -0
  85. /package/dist/tooling/cli/{development → legacy/development}/lease.d.ts +0 -0
  86. /package/dist/tooling/cli/{development → legacy/development}/lease.js +0 -0
  87. /package/dist/tooling/cli/{development → legacy/development}/lifecycle.d.ts +0 -0
  88. /package/dist/tooling/cli/{development → legacy/development}/lifecycle.js +0 -0
  89. /package/dist/tooling/cli/{development → legacy/development}/project-imports.d.ts +0 -0
  90. /package/dist/tooling/cli/{development → legacy/development}/project-imports.js +0 -0
  91. /package/dist/tooling/cli/{development → legacy/development}/project-lock.d.ts +0 -0
  92. /package/dist/tooling/cli/{development → legacy/development}/project-lock.js +0 -0
  93. /package/dist/tooling/cli/{development → legacy/development}/rebuild.d.ts +0 -0
  94. /package/dist/tooling/cli/{development → legacy/development}/rebuild.js +0 -0
  95. /package/dist/tooling/cli/{development → legacy/development}/source-watch.d.ts +0 -0
  96. /package/dist/tooling/cli/{development → legacy/development}/source-watch.js +0 -0
  97. /package/dist/tooling/cli/{development → legacy/development}/sources.d.ts +0 -0
  98. /package/dist/tooling/cli/{development → legacy/development}/sources.js +0 -0
@@ -1,7 +1,7 @@
1
- import type { DeploymentSummaryV1, FrozenConfigurationV1 } from '../address/index.js';
1
+ import type { FrozenConfigurationV1 } from '../address/index.js';
2
2
  import type { Bundler } from './bundle/index.js';
3
3
  import type { ArtifactSource, DeployContext, DeployResult, PrepareContext } from './legacy/index.js';
4
- import type { ConfigureContext, ListContext, Placement, PlacementContext, ReleaseDeployContext, ReleaseDeployResult, RetainContext } from './release/index.js';
4
+ import type { ConfigureContext, ListContext, ListedDeployment, Placement, PlacementContext, ReleaseDeployContext, ReleaseDeployResult, RetainContext } from './release/index.js';
5
5
  /** What `admit` receives when `defineProject` binds an adapter to one Environment. */
6
6
  export interface AdapterEnvironmentContext {
7
7
  readonly environment: string;
@@ -32,12 +32,16 @@ export interface Adapter<Parameters extends object = object> {
32
32
  placement(parameters: Parameters, context: PlacementContext): Promise<Placement>;
33
33
  /** Create, or reuse, the immutable deployment of one sealed release. */
34
34
  deployRelease(parameters: Parameters, context: ReleaseDeployContext): Promise<ReleaseDeployResult>;
35
- /** The deployments of one origin the host keeps for the caller. */
36
- list?(parameters: Parameters, context: ListContext): Promise<readonly DeploymentSummaryV1[]>;
35
+ /**
36
+ * The deployments of one Environment of one origin the host keeps for the caller, each with
37
+ * where it is called. No effect at the host.
38
+ */
39
+ list?(parameters: Parameters, context: ListContext): Promise<readonly ListedDeployment[]>;
37
40
  /**
38
41
  * Keep one published deployment where the host has no registry principal to mark it (a platform
39
- * namespace). Called only after its Publication commits. Absent: the registry marks it (Admin's
40
- * Services).
42
+ * namespace). Called only after its Publication commits. Rejects with a `RetainRefusal` when the
43
+ * host can no longer keep it (absent or retired), which no rerun changes; any other rejection is
44
+ * transient. Absent: the registry marks it (Admin's Services).
41
45
  */
42
46
  retain?(parameters: Parameters, context: RetainContext): Promise<void>;
43
47
  /**
@@ -61,7 +65,7 @@ export interface AdapterInput<Parameters extends object> {
61
65
  configure(parameters: Parameters, context: ConfigureContext): FrozenConfigurationV1;
62
66
  placement(parameters: Parameters, context: PlacementContext): Promise<Placement>;
63
67
  deployRelease(parameters: Parameters, context: ReleaseDeployContext): Promise<ReleaseDeployResult>;
64
- list?(parameters: Parameters, context: ListContext): Promise<readonly DeploymentSummaryV1[]>;
68
+ list?(parameters: Parameters, context: ListContext): Promise<readonly ListedDeployment[]>;
65
69
  retain?(parameters: Parameters, context: RetainContext): Promise<void>;
66
70
  /** @deprecated Legacy direct-mode path (CT33) only. Replacement: `configure`, `placement`. */
67
71
  prepare?(parameters: Parameters, context: PrepareContext): Promise<ArtifactSource>;
@@ -1,5 +1,6 @@
1
1
  export type { Adapter, AdapterEnvironmentContext, AdapterInput } from './adapter.js';
2
2
  export { defineAdapter, defineDeployment, isAdapter } from './define.js';
3
+ export { RetainRefusal } from './release/refusal.js';
3
4
  export type * from './bundle/index.js';
4
5
  export type * from './release/index.js';
5
6
  /** @deprecated The contract before adapter interface v2; see `./legacy/index.ts`. */
@@ -1 +1,2 @@
1
1
  export { defineAdapter, defineDeployment, isAdapter } from './define.js';
2
+ export { RetainRefusal } from './release/refusal.js';
@@ -8,14 +8,12 @@
8
8
  * created or reused, and installs nothing.
9
9
  *
10
10
  * Short-term consumers: the legacy direct-mode path (CT33), which `astrale-domain deploy` and
11
- * `astrale-domain dev` run through these operations:
12
- * - adapter-cloudflare direct mode (`route`, `workerName`, `identityIssuer`, `addressing`,
13
- * `signingIdentity`, or no `namespace`), which serves the configurations of domains ai-gateway,
14
- * closing, grc, integrations and issues (until SV15), domains organization (until it leaves
15
- * direct mode, AM-147), the Services `beta` and `prod` (until SV12), `development` (until SV9)
16
- * and frozen `admin-beta` (until D19) environments, shell (until SH2) and its frozen `legacy-v3`
17
- * (until D22), and ui:domain (until UI1);
18
- * - adapter-astrale, until S8 gives it `deployRelease`.
11
+ * `astrale-domain dev` run through these operations: adapter-cloudflare direct mode (`route`,
12
+ * `workerName`, `identityIssuer`, `addressing`, `signingIdentity`, or no `namespace`), which serves
13
+ * the configurations of domains ai-gateway, closing, grc, integrations and issues (until SV15),
14
+ * domains organization (until it leaves direct mode, AM-147), the Services `beta` and `prod` (until
15
+ * SV12), `development` (until SV9) and frozen `admin-beta` (until D19) environments, shell (until
16
+ * SH2) and its frozen `legacy-v3` (until D22), and ui:domain (until UI1).
19
17
  *
20
18
  * Removal: D10, once no configuration on any repository's main selects the direct-mode path
21
19
  * (CT33, AM-147); it deletes these types with `prepare`/`deploy`, `src/deployment/release/legacy`
@@ -75,10 +75,16 @@ export interface ReleaseDeployContext {
75
75
  /** Parent-owned lifecycle cancellation shared by every provider effect. */
76
76
  readonly signal: AbortSignal;
77
77
  }
78
- /** What `list` receives: the origin whose deployments the host lists for the caller. */
78
+ /**
79
+ * What `list` receives: the origin and the Environment whose deployments the host lists for the
80
+ * caller. It answers without any effect at the host.
81
+ */
79
82
  export interface ListContext {
80
83
  readonly origin: string;
84
+ readonly environment: string;
85
+ /** Parent-owned lifecycle cancellation. */
81
86
  readonly signal: AbortSignal;
87
+ /** Optional command-scoped identity override (`--as`). */
82
88
  readonly identity?: string;
83
89
  }
84
90
  /** What `retain` receives: the label of the published deployment to keep. */
@@ -1,2 +1,3 @@
1
1
  export type { ConfigureContext, ListContext, Placement, PlacementContext, ReleaseDeployContext, RetainContext, } from './context.js';
2
+ export type { DeploymentCallTarget, ListedDeployment } from './list.js';
2
3
  export type { DeploymentSecretsState, FailedReleaseDeployResult, MutationKnowledge, ReadyReleaseDeployResult, ReleaseDeploymentPhase, ReleaseDeployResult, } from './result.js';
@@ -0,0 +1,41 @@
1
+ import type { DeploymentSummaryV1 } from '../../address/index.js';
2
+ /**
3
+ * Where one listed deployment is called on its host, so that an operator can act on that
4
+ * deployment alone, such as rotating one of its secrets in place (AM-4'):
5
+ *
6
+ * - `services`: a deployment Admin's Services hosts, called on the Admin instance with
7
+ * `astrale call "<path>.method.setSecret" --admin` (`--admin=<admin>` when `admin` names the
8
+ * Admin bookmark). `path` is the deployment's node, `@<id>`, qualified by its class:
9
+ * `@<id>::services.astrale.ai:class.CloudflareDeployment`.
10
+ * - `namespace`: a deployment of a platform dispatch namespace, which has no Services node: the
11
+ * namespace and the script the per-script tooling of that namespace takes.
12
+ */
13
+ export type DeploymentCallTarget = {
14
+ readonly kind: 'services';
15
+ readonly path: string;
16
+ /** The Admin bookmark the deployment is reached through; the CLI's own Admin target when absent. */
17
+ readonly admin?: string;
18
+ } | {
19
+ readonly kind: 'namespace';
20
+ readonly namespace: string;
21
+ readonly script: string;
22
+ };
23
+ /**
24
+ * One deployment as an adapter's `list` returns it: what its host knows of it, its record as the
25
+ * host stores it, and where it is called. `lastCallAt`, and a preview's `expiresAt`, are as of the
26
+ * listing: an adapter whose host records calls only now and then reads the calls counted since, and
27
+ * one that cannot read them for want of a permission omits both rather than print stale values.
28
+ *
29
+ * The adapter does not admit the record. The listing admits it with `acceptDeploymentRecord`, and a
30
+ * record it refuses (one a host on an older SDK still admits, say) never fails the listing: that
31
+ * deployment is listed from the facts its host owns.
32
+ */
33
+ export interface ListedDeployment extends Omit<DeploymentSummaryV1, 'record'> {
34
+ /**
35
+ * The record as the host stores it, unadmitted, whatever value that is (JSON `null` included).
36
+ * Absent when the host keeps no record of the deployment: a platform namespace keeps none until
37
+ * it activates the deployment.
38
+ */
39
+ readonly record?: unknown;
40
+ readonly callTarget: DeploymentCallTarget;
41
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Why the host can no longer keep one published deployment (`Adapter.retain`): it is `absent`
3
+ * (the host holds no deployment of that label, or it was deleted) or `retired` (withdrawn, never
4
+ * served again). No rerun keeps it; a new version publishes a new deployment. Any other rejection
5
+ * of `retain` is transient: once it has passed, a rerun keeps the deployment.
6
+ */
7
+ export declare class RetainRefusal extends Error {
8
+ readonly reason: 'absent' | 'retired';
9
+ constructor(reason: RetainRefusal['reason'], message: string);
10
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Why the host can no longer keep one published deployment (`Adapter.retain`): it is `absent`
3
+ * (the host holds no deployment of that label, or it was deleted) or `retired` (withdrawn, never
4
+ * served again). No rerun keeps it; a new version publishes a new deployment. Any other rejection
5
+ * of `retain` is transient: once it has passed, a rerun keeps the deployment.
6
+ */
7
+ export class RetainRefusal extends Error {
8
+ reason;
9
+ constructor(reason, message) {
10
+ super(message);
11
+ this.name = 'RetainRefusal';
12
+ this.reason = reason;
13
+ }
14
+ }
@@ -17,7 +17,7 @@ export interface DeploymentSummaryV1 {
17
17
  readonly retention: 'preview' | 'published';
18
18
  readonly createdAt: string;
19
19
  readonly lastCallAt?: string;
20
- /** A preview's: 30 days after its creation or its last call, whichever is later. */
20
+ /** A preview's: 30 days after its activation or its last call, whichever is later (AM-123). */
21
21
  readonly expiresAt?: string;
22
22
  readonly retiredAt?: string;
23
23
  readonly retirement?: 'expired' | 'withdrawn';
@@ -1,5 +1,5 @@
1
1
  export { defineAdapter, defineDeployment, isAdapter } from './adapter/index.js';
2
- export type { Adapter, AdapterEnvironmentContext, AdapterInput, AddressingPlan, ArtifactFile, ArtifactSource, Bundle, BundleContext, Bundler, BundleSource, ConfigureContext, DeployContext, DeploymentPhase, DeploymentProgress, DeploymentSecretsState, DeployResult, FailedDeployResult, FailedReleaseDeployResult, LegacyAdapter, LegacyAdapterInput, ListContext, MutationKnowledge, Placement, PlacementContext, PreparedArtifact, PreparedArtifactFile, PrepareContext, ReadyDeployResult, ReadyReleaseDeployResult, ReleaseDeployContext, ReleaseDeploymentPhase, ReleaseDeployResult, RetainContext, } from './adapter/index.js';
2
+ export type { Adapter, AdapterEnvironmentContext, AdapterInput, AddressingPlan, ArtifactFile, ArtifactSource, Bundle, BundleContext, Bundler, BundleSource, ConfigureContext, DeployContext, DeploymentCallTarget, DeploymentPhase, DeploymentProgress, DeploymentSecretsState, DeployResult, FailedDeployResult, FailedReleaseDeployResult, LegacyAdapter, LegacyAdapterInput, ListContext, ListedDeployment, MutationKnowledge, Placement, PlacementContext, PreparedArtifact, PreparedArtifactFile, PrepareContext, ReadyDeployResult, ReadyReleaseDeployResult, ReleaseDeployContext, ReleaseDeploymentPhase, ReleaseDeployResult, RetainContext, } from './adapter/index.js';
3
3
  export { compile, isBuild } from './build/index.js';
4
4
  export type { Build, BuildBundle, BuildDigest, BuildManifestV1, BuildSchema, } from './build/index.js';
5
5
  export { deploy } from './deploy.js';
@@ -8,8 +8,8 @@
8
8
  * seal the `DomainRelease` v4 of an immutable deployment from its build digest and URL.
9
9
  *
10
10
  * Short-term consumers:
11
- * - the direct-mode deploy path (`prepare`/`deploy` of adapter-cloudflare and adapter-astrale,
12
- * whose `DeployResult.release` is this Release) and the stable Worker that assembles its Release
11
+ * - the direct-mode deploy path (`prepare`/`deploy` of adapter-cloudflare, whose
12
+ * `DeployResult.release` is this Release) and the stable Worker that assembles its Release
13
13
  * at runtime, which serve the direct-mode configurations of domains ai-gateway, closing, grc,
14
14
  * integrations and issues (until SV15), domains organization (until it leaves direct mode,
15
15
  * AM-147), the Services `beta` and `prod` (until SV12), `development` (until SV9) and frozen
@@ -8,8 +8,8 @@
8
8
  * seal the `DomainRelease` v4 of an immutable deployment from its build digest and URL.
9
9
  *
10
10
  * Short-term consumers:
11
- * - the direct-mode deploy path (`prepare`/`deploy` of adapter-cloudflare and adapter-astrale,
12
- * whose `DeployResult.release` is this Release) and the stable Worker that assembles its Release
11
+ * - the direct-mode deploy path (`prepare`/`deploy` of adapter-cloudflare, whose
12
+ * `DeployResult.release` is this Release) and the stable Worker that assembles its Release
13
13
  * at runtime, which serve the direct-mode configurations of domains ai-gateway, closing, grc,
14
14
  * integrations and issues (until SV15), domains organization (until it leaves direct mode,
15
15
  * AM-147), the Services `beta` and `prod` (until SV12), `development` (until SV9) and frozen
@@ -6,7 +6,7 @@ import type { ReadinessOptions } from '../fetch.js';
6
6
  *
7
7
  * @deprecated Replacement: `verifyRelease`, the readiness of an immutable deployment at
8
8
  * `release.json` (release digest and build digest). Consumer: the direct-mode deploy path of
9
- * adapter-cloudflare and adapter-astrale (the consumers of `deployment/release/legacy/index.ts`).
9
+ * adapter-cloudflare (the consumers of `deployment/release/legacy/index.ts`).
10
10
  * Removal: D10, with that path.
11
11
  */
12
12
  export declare function verifyPublication(release: legacy.Release, options?: ReadinessOptions): Promise<publication.Publication>;
@@ -5,7 +5,7 @@ import { bounded, fetchRequired, MAXIMUM_BUNDLE_BYTES, MAXIMUM_DOCUMENT_BYTES, t
5
5
  *
6
6
  * @deprecated Replacement: `verifyRelease`, the readiness of an immutable deployment at
7
7
  * `release.json` (release digest and build digest). Consumer: the direct-mode deploy path of
8
- * adapter-cloudflare and adapter-astrale (the consumers of `deployment/release/legacy/index.ts`).
8
+ * adapter-cloudflare (the consumers of `deployment/release/legacy/index.ts`).
9
9
  * Removal: D10, with that path.
10
10
  */
11
11
  export async function verifyPublication(release, options = {}) {
@@ -5,6 +5,7 @@ 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';
8
9
  /**
9
10
  * How long a callback Session reuses a learned route. It stays at most the Kernel's in-flight
10
11
  * issuer window (`KERNEL_INFLIGHT_ISSUER_MS`, Host default 300 s; CT11): a route learned to a
@@ -26,10 +27,13 @@ export declare function authenticate(credentialInput: CredentialInput, expectedK
26
27
  readonly signal: AbortSignal;
27
28
  }, configuration: AuthenticationConfiguration): Promise<AuthenticatedInvocation>;
28
29
  /**
29
- * The Domain's own authority toward one Kernel, for work no caller credential carries: a durable
30
- * 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.
31
35
  */
32
- export declare function executorSession(kernel: IssuerId, execution: {
36
+ export declare function executorSession(kernel: IssuerId, executionId: NodeId, execution: {
33
37
  readonly deadline: number;
34
38
  readonly signal: AbortSignal;
35
39
  }, configuration: AuthenticationConfiguration): ClientSession;
@@ -79,16 +79,19 @@ export async function authenticate(credentialInput, expectedKernel, execution, c
79
79
  });
80
80
  }
81
81
  /**
82
- * The Domain's own authority toward one Kernel, for work no caller credential carries: a durable
83
- * 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.
84
87
  */
85
- export function executorSession(kernel, execution, configuration) {
88
+ export function executorSession(kernel, executionId, execution, configuration) {
86
89
  const admitted = httpIssuer(kernel, configuration.policy.allowInsecureHttp === true);
87
90
  admitEndpoint(invocationUrl(admitted), configuration.policy);
88
- return callbackSession(admitted, selfIdentity, undefined, execution, configuration);
91
+ return callbackSession(admitted, selfIdentity, undefined, execution, configuration, executionId);
89
92
  }
90
- function callbackSession(kernel, expression, carrier, execution, configuration) {
91
- 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);
92
95
  return new ClientSession({
93
96
  kernel,
94
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 }),
@@ -3,6 +3,7 @@ import type * as releaseProtocol from '@astrale-os/kernel-protocol/release';
3
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';
@@ -16,10 +17,11 @@ export interface Identity extends Issuer, InvocationAuthority {
16
17
  */
17
18
  delivery(served: releaseProtocol.DomainRelease | releaseProtocol.legacy.Publication): release.delivery.Provider;
18
19
  /**
19
- * The Domain's own authority toward one Kernel for work no caller credential carries, such as a
20
- * durable run. Required to serve durable Workflows; the caller closes the Session.
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.
21
23
  */
22
- executor?(kernel: IssuerId, execution: {
24
+ executor?(kernel: IssuerId, executionId: NodeId, execution: {
23
25
  readonly deadline: number;
24
26
  readonly signal: AbortSignal;
25
27
  }): ClientSession;
@@ -51,7 +51,7 @@ export function createIdentity(input) {
51
51
  ...(exchangeProvider === undefined ? {} : { tokenExchange: exchangeProvider }),
52
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
  }
@@ -84,7 +84,7 @@ function durableContext(input, context, envelope) {
84
84
  /** One journaled unit of work acting as the Domain, with keys derived from its name. */
85
85
  const journal = (name, execute) => Promise.resolve(context.run(name, async () => {
86
86
  const deadline = Date.now() + serving.stepTimeoutMs;
87
- const session = input.executor(execution.kernel, { deadline, signal });
87
+ const session = input.executor(execution.kernel, execution.id, { deadline, signal });
88
88
  try {
89
89
  const kernel = keyed(bindSessionOf(session, deadline, signal), await keySequence(execution.id, name));
90
90
  const output = await execute(Object.freeze({
@@ -15,12 +15,13 @@ import type { Digest } from '@astrale-os/kernel-protocol/artifact';
15
15
  * hexadecimal digits names a plain preview, and the commit token is always printed in lower case,
16
16
  * like `git describe`. An environment outside the `defineProject` grammar is rendered as `?`, so no
17
17
  * record can put control characters or a ` · ` of its own in the name. Likewise only canonical
18
- * published versions name a deployment.
18
+ * published versions name a deployment. A deployment named without its digests (one whose record
19
+ * is not admitted) is never named by a published version.
19
20
  */
20
21
  export declare function deploymentName(deployment: {
21
22
  readonly environment: string;
22
- readonly releaseDigest: Digest;
23
- readonly buildDigest: Digest;
23
+ readonly releaseDigest?: Digest;
24
+ readonly buildDigest?: Digest;
24
25
  readonly commit: {
25
26
  readonly sha: string;
26
27
  readonly dirty: boolean;
@@ -21,17 +21,18 @@ const UNKNOWN_ENVIRONMENT = '?';
21
21
  * hexadecimal digits names a plain preview, and the commit token is always printed in lower case,
22
22
  * like `git describe`. An environment outside the `defineProject` grammar is rendered as `?`, so no
23
23
  * record can put control characters or a ` · ` of its own in the name. Likewise only canonical
24
- * published versions name a deployment.
24
+ * published versions name a deployment. A deployment named without its digests (one whose record
25
+ * is not admitted) is never named by a published version.
25
26
  */
26
27
  export function deploymentName(deployment, publications) {
27
28
  const { commit } = deployment;
28
29
  const environment = typeof deployment.environment === 'string' && ENVIRONMENT_NAME.test(deployment.environment)
29
30
  ? deployment.environment
30
31
  : UNKNOWN_ENVIRONMENT;
31
- const release = highest(publications.filter(({ releaseDigest }) => releaseDigest === deployment.releaseDigest));
32
+ const release = highest(publications.filter(({ releaseDigest }) => deployment.releaseDigest !== undefined && releaseDigest === deployment.releaseDigest));
32
33
  if (release !== undefined)
33
34
  return release;
34
- const build = highest(publications.filter(({ buildDigest }) => buildDigest === deployment.buildDigest));
35
+ const build = highest(publications.filter(({ buildDigest }) => deployment.buildDigest !== undefined && buildDigest === deployment.buildDigest));
35
36
  if (build !== undefined)
36
37
  return `${build} · ${environment}`;
37
38
  if (commit === null || typeof commit.sha !== 'string' || !SHA.test(commit.sha)) {
@@ -4,8 +4,10 @@ import { ENVIRONMENT_NAME } from '../deployment/environment.js';
4
4
  import { isTests } from '../testing/index.js';
5
5
  import { installCommand } from './install-command.js';
6
6
  const admittedProjects = new WeakSet();
7
- /** The adapter name of adapter-astrale, whose instance mode once read `installation`. */
7
+ /** The adapter name of adapter-astrale, whose removed instance mode once read `installation`. */
8
8
  const ASTRALE_ADAPTER = 'astrale';
9
+ /** The one Environment adapter-astrale deploys without an explicit organisation (AM-7). */
10
+ const ASTRALE_DEFAULT_ORGANIZATION_ENVIRONMENT = 'development';
9
11
  /** Capture one inert Project definition without loading entrypoints or performing effects. */
10
12
  export function defineProject(input) {
11
13
  const value = record(input, 'Project definition');
@@ -80,10 +82,10 @@ function admitEntrypoints(input) {
80
82
  * `installation` is refused before any effect, with the commands that replace it. Its only
81
83
  * consumer pins an SDK older than this refusal.
82
84
  *
83
- * adapter-astrale took its Services instance, and the identity of its Services calls, from
84
- * `installation` when `astrale({ instance })` named none. For such an Environment the guidance
85
- * also moves the instance into the adapter and passes the identity to the deploy, so following
86
- * it deploys exactly where and as the configuration did.
85
+ * adapter-astrale deploys on Admin's Services, never through the installation's instance: outside
86
+ * development its Environment also names the organisation that holds its deployment line (AM-7),
87
+ * which the guidance adds when the adapter names none. The installation's instance and identity
88
+ * move to the install command.
87
89
  */
88
90
  function installationRefusal(environment, name) {
89
91
  const declared = environment.installation;
@@ -97,15 +99,14 @@ function installationRefusal(environment, name) {
97
99
  const instance = stable(installation.instance);
98
100
  const identity = stable(installation.identity);
99
101
  const deployment = environment.deployment;
100
- const astrale = isDeployment(deployment) &&
102
+ const organization = isDeployment(deployment) &&
101
103
  deployment.adapter.name === ASTRALE_ADAPTER &&
102
- deployment.parameters.instance === undefined;
103
- const adapterInstance = astrale
104
- ? `, name its instance in \`astrale({ instance: '${instance ?? '<instance>'}' })\``
104
+ name !== ASTRALE_DEFAULT_ORGANIZATION_ENVIRONMENT &&
105
+ deployment.parameters.organization === undefined
106
+ ? ", name the organisation that holds its deployment line in `astrale({ organization: '<Identity id>' })`"
105
107
  : '';
106
- const deployIdentity = astrale && identity !== undefined ? ` --as ${identity}` : '';
107
108
  return (`Project Environment ${name} declares installation, and a deploy no longer installs. ` +
108
- `Remove \`installation\`${adapterInstance}, run \`astrale-domain deploy ${name}${deployIdentity}\`, ` +
109
+ `Remove \`installation\`${organization}, run \`astrale-domain deploy ${name}\`, ` +
109
110
  `then install the URL it prints with \`${installCommand(instance, identity)}\`.`);
110
111
  }
111
112
  /** A declared coordinate worth repeating in guidance: a non-empty single-line trimmed string. */
@@ -1,5 +1,6 @@
1
1
  import type { LintReportFormat } from '../linter/index.js';
2
- export declare const COMMANDS: readonly ['dev', 'build', 'deploy', 'test', 'lint', 'package', 'upgrade'];
2
+ import { type Version } from '../../platform/versioning/index.js';
3
+ export declare const COMMANDS: readonly ['dev', 'build', 'deploy', 'diff', 'list', 'publish', 'test', 'lint', 'package', 'upgrade', 'yank'];
3
4
  export type Command = (typeof COMMANDS)[number];
4
5
  export interface ParsedArgs {
5
6
  readonly command: Command;
@@ -13,6 +14,11 @@ export interface ParsedArgs {
13
14
  readonly channel?: string;
14
15
  readonly check?: boolean;
15
16
  readonly json?: boolean;
17
+ /** `yank`: the published version it names. */
18
+ readonly version?: Version;
19
+ /** `yank --undo`: restore the version instead of yanking it. */
20
+ readonly undo?: boolean;
21
+ readonly allowDirty?: boolean;
16
22
  }
17
23
  /** Parse the frozen `astrale-domain` command grammar without performing effects. */
18
24
  export declare function parseArgs(argv: readonly string[]): ParsedArgs;