@astrale-os/sdk 0.5.0-beta.99 → 0.6.0-beta.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 (270) hide show
  1. package/README.md +165 -2
  2. package/dist/application/action/action.d.ts +7 -4
  3. package/dist/application/action/authoring.d.ts +2 -1
  4. package/dist/application/action/context.d.ts +18 -13
  5. package/dist/application/action/define.d.ts +5 -1
  6. package/dist/application/action/define.js +6 -1
  7. package/dist/application/action/index.d.ts +2 -1
  8. package/dist/application/dependency/index.d.ts +1 -0
  9. package/dist/application/dependency/invoker.d.ts +26 -0
  10. package/dist/application/error/error.d.ts +23 -0
  11. package/dist/application/error/error.js +87 -0
  12. package/dist/application/error/index.d.ts +2 -0
  13. package/dist/application/error/index.js +1 -0
  14. package/dist/application/index.d.ts +2 -2
  15. package/dist/application/integration/authentication.d.ts +10 -0
  16. package/dist/application/integration/authentication.typecheck.js +18 -0
  17. package/dist/application/integration/client.d.ts +2 -0
  18. package/dist/application/integration/client.js +19 -2
  19. package/dist/application/integration/index.d.ts +1 -0
  20. package/dist/application/integration/operation.d.ts +3 -0
  21. package/dist/application/mutation/authoring/builder.js +2 -2
  22. package/dist/application/mutation/authoring/endpoint.d.ts +3 -3
  23. package/dist/application/mutation/authoring/endpoint.js +9 -0
  24. package/dist/application/mutation/failure.js +13 -7
  25. package/dist/application/mutation/index.d.ts +1 -0
  26. package/dist/application/requirements/{profiles.d.ts → core.d.ts} +5 -3
  27. package/dist/application/requirements/{profiles.js → core.js} +6 -6
  28. package/dist/application/requirements/index.d.ts +4 -4
  29. package/dist/application/requirements/index.js +5 -5
  30. package/dist/application/requirements/requirement.d.ts +3 -2
  31. package/dist/application/runtime/authoring.d.ts +1 -0
  32. package/dist/application/runtime/callables.js +2 -2
  33. package/dist/application/runtime/declarations.d.ts +43 -0
  34. package/dist/application/runtime/define.d.ts +2 -1
  35. package/dist/application/view/index.d.ts +1 -1
  36. package/dist/application/view/route.d.ts +4 -0
  37. package/dist/application/view/route.js +5 -1
  38. package/dist/application/workflow/authoring.d.ts +1 -0
  39. package/dist/application/workflow/context.d.ts +2 -1
  40. package/dist/application/workflow/define.d.ts +5 -1
  41. package/dist/application/workflow/define.js +6 -1
  42. package/dist/application/workflow/index.d.ts +1 -0
  43. package/dist/application/workflow/runner/runner.d.ts +3 -2
  44. package/dist/application/workflow/workflow.d.ts +4 -3
  45. package/dist/deployment/adapter/adapter.d.ts +12 -7
  46. package/dist/deployment/adapter/define.d.ts +5 -2
  47. package/dist/deployment/adapter/define.js +15 -17
  48. package/dist/deployment/adapter/deploy/context.d.ts +6 -0
  49. package/dist/deployment/adapter/deploy/result.d.ts +2 -0
  50. package/dist/deployment/adapter/index.d.ts +2 -3
  51. package/dist/deployment/adapter/index.js +1 -1
  52. package/dist/deployment/adapter/prepare/context.d.ts +13 -5
  53. package/dist/deployment/authoring.d.ts +1 -1
  54. package/dist/deployment/build/compile.js +21 -19
  55. package/dist/deployment/build/frontend/compilation.d.ts +2 -1
  56. package/dist/deployment/build/frontend/compilation.js +1 -0
  57. package/dist/deployment/build/material.js +5 -5
  58. package/dist/deployment/deploy.d.ts +10 -4
  59. package/dist/deployment/deploy.js +5 -5
  60. package/dist/deployment/deployment.d.ts +8 -5
  61. package/dist/deployment/deployment.js +10 -1
  62. package/dist/deployment/index.d.ts +5 -4
  63. package/dist/deployment/index.js +3 -2
  64. package/dist/deployment/release/addressing.d.ts +6 -2
  65. package/dist/deployment/release/addressing.js +9 -4
  66. package/dist/deployment/release/publication/callables.js +1 -1
  67. package/dist/deployment/release/publication/index.d.ts +1 -1
  68. package/dist/deployment/release/publication/index.js +1 -1
  69. package/dist/deployment/release/publication/routes.js +1 -1
  70. package/dist/deployment/release/publication/seal.d.ts +0 -1
  71. package/dist/deployment/release/publication/seal.js +4 -5
  72. package/dist/deployment/release/publication/views.js +2 -1
  73. package/dist/deployment/verify/preflight/artifact.js +1 -1
  74. package/dist/deployment/verify/readiness/deployment.js +7 -3
  75. package/dist/deployment/verify/readiness/identity.js +1 -1
  76. package/dist/deployment/verify/readiness/publication.js +2 -2
  77. package/dist/execution/identity/authentication.js +0 -1
  78. package/dist/execution/identity/exchange.d.ts +1 -0
  79. package/dist/execution/identity/exchange.js +1 -1
  80. package/dist/execution/identity/jwks.js +1 -1
  81. package/dist/execution/invocation/admission/authentication.d.ts +6 -3
  82. package/dist/execution/invocation/admission/authentication.js +16 -6
  83. package/dist/execution/invocation/admission/authority.d.ts +2 -2
  84. package/dist/execution/invocation/dependency/bind.d.ts +5 -0
  85. package/dist/execution/invocation/dependency/bind.js +68 -0
  86. package/dist/execution/invocation/dependency/index.d.ts +1 -0
  87. package/dist/execution/invocation/dependency/index.js +1 -0
  88. package/dist/execution/invocation/dispatch/action.js +19 -2
  89. package/dist/execution/invocation/dispatch/context.d.ts +4 -4
  90. package/dist/execution/invocation/dispatch/context.js +29 -9
  91. package/dist/execution/invocation/dispatch/workflow.js +17 -4
  92. package/dist/execution/invocation/integration/authentication.d.ts +5 -0
  93. package/dist/execution/invocation/integration/authentication.js +53 -0
  94. package/dist/execution/invocation/integration/call.d.ts +7 -1
  95. package/dist/execution/invocation/integration/call.js +8 -3
  96. package/dist/execution/invocation/integration/clients.d.ts +2 -2
  97. package/dist/execution/invocation/integration/clients.js +2 -2
  98. package/dist/execution/invocation/lifecycle/active.js +30 -5
  99. package/dist/execution/invocation/result/errors.d.ts +1 -0
  100. package/dist/execution/invocation/result/errors.js +15 -10
  101. package/dist/execution/service/create.js +3 -1
  102. package/dist/execution/service/service.d.ts +1 -1
  103. package/dist/index.d.ts +3 -1
  104. package/dist/index.js +1 -0
  105. package/dist/platform/auth/index.d.ts +1 -1
  106. package/dist/platform/auth/index.js +0 -1
  107. package/dist/platform/graph/alias.d.ts +6 -0
  108. package/dist/platform/graph/alias.js +6 -0
  109. package/dist/platform/graph/document/index.d.ts +2 -1
  110. package/dist/platform/graph/document/index.js +2 -1
  111. package/dist/platform/graph/index.d.ts +2 -1
  112. package/dist/platform/graph/index.js +2 -1
  113. package/dist/platform/schema/class-authoring.d.ts +37 -0
  114. package/dist/platform/schema/class-authoring.js +20 -0
  115. package/dist/platform/schema/class-icon.d.ts +15 -0
  116. package/dist/platform/schema/class-icon.js +46 -0
  117. package/dist/platform/schema/error.d.ts +11 -0
  118. package/dist/platform/schema/error.js +34 -0
  119. package/dist/platform/schema/errors/index.d.ts +3 -0
  120. package/dist/platform/schema/errors/index.js +2 -0
  121. package/dist/platform/schema/icons/index.d.ts +2 -0
  122. package/dist/platform/schema/icons/index.js +2 -0
  123. package/dist/platform/schema/index.d.ts +20 -13
  124. package/dist/platform/schema/index.js +9 -4
  125. package/dist/platform/schema/kernel.d.ts +22 -0
  126. package/dist/platform/schema/kernel.js +5 -0
  127. package/dist/platform/schema/node-id.d.ts +3 -0
  128. package/dist/platform/schema/node-id.js +6 -0
  129. package/dist/platform/schema/property.d.ts +12 -0
  130. package/dist/platform/schema/property.js +3 -0
  131. package/dist/platform/schema/schema-authoring.d.ts +48 -0
  132. package/dist/platform/schema/schema-authoring.js +3 -0
  133. package/dist/platform/schema/state-property.d.ts +11 -0
  134. package/dist/platform/schema/state-property.js +3 -0
  135. package/dist/project/admit.d.ts +4 -0
  136. package/dist/project/admit.js +22 -0
  137. package/dist/project/define.d.ts +12 -0
  138. package/dist/project/define.js +106 -0
  139. package/dist/project/index.d.ts +4 -0
  140. package/dist/project/index.js +2 -0
  141. package/dist/project/project.d.ts +24 -0
  142. package/dist/project/project.js +1 -0
  143. package/dist/testing/dataset/admission.d.ts +13 -0
  144. package/dist/testing/dataset/admission.js +107 -0
  145. package/dist/testing/dataset/builder.d.ts +42 -0
  146. package/dist/testing/dataset/builder.js +127 -0
  147. package/dist/testing/dataset/codec.d.ts +6 -0
  148. package/dist/testing/dataset/codec.js +113 -0
  149. package/dist/testing/dataset/dataset.d.ts +58 -0
  150. package/dist/testing/dataset/dataset.js +2 -0
  151. package/dist/testing/dataset/define.d.ts +33 -0
  152. package/dist/testing/dataset/define.js +105 -0
  153. package/dist/testing/dataset/index.d.ts +8 -0
  154. package/dist/testing/dataset/index.js +4 -0
  155. package/dist/testing/dataset/references.d.ts +14 -0
  156. package/dist/testing/dataset/references.js +56 -0
  157. package/dist/testing/index.d.ts +9 -0
  158. package/dist/testing/index.js +5 -0
  159. package/dist/testing/load.d.ts +14 -0
  160. package/dist/testing/load.js +44 -0
  161. package/dist/testing/reference.d.ts +11 -0
  162. package/dist/testing/reference.js +19 -0
  163. package/dist/testing/tests.d.ts +12 -0
  164. package/dist/testing/tests.js +31 -0
  165. package/dist/tooling/cli/arguments.d.ts +7 -4
  166. package/dist/tooling/cli/arguments.js +82 -107
  167. package/dist/tooling/cli/astrale/authority.d.ts +5 -0
  168. package/dist/tooling/cli/astrale/authority.js +11 -0
  169. package/dist/tooling/cli/astrale/executable.d.ts +2 -0
  170. package/dist/tooling/cli/astrale/executable.js +47 -0
  171. package/dist/tooling/cli/astrale/failure.d.ts +6 -0
  172. package/dist/tooling/cli/astrale/failure.js +48 -0
  173. package/dist/tooling/cli/astrale/instance.d.ts +11 -0
  174. package/dist/tooling/cli/astrale/instance.js +52 -0
  175. package/dist/tooling/cli/astrale/process.d.ts +13 -0
  176. package/dist/tooling/cli/astrale/process.js +94 -0
  177. package/dist/tooling/cli/astrale/version.d.ts +18 -0
  178. package/dist/tooling/cli/astrale/version.js +55 -0
  179. package/dist/tooling/cli/bun.js +1 -1
  180. package/dist/tooling/cli/credential.d.ts +2 -0
  181. package/dist/tooling/cli/credential.js +57 -0
  182. package/dist/tooling/cli/development/candidate.d.ts +25 -0
  183. package/dist/tooling/cli/development/candidate.js +176 -0
  184. package/dist/tooling/cli/development/deployment.d.ts +16 -0
  185. package/dist/tooling/cli/development/deployment.js +39 -0
  186. package/dist/tooling/cli/development/develop.d.ts +4 -3
  187. package/dist/tooling/cli/development/develop.js +125 -289
  188. package/dist/tooling/cli/development/lease.d.ts +18 -0
  189. package/dist/tooling/cli/development/lease.js +163 -0
  190. package/dist/tooling/cli/development/lifecycle.js +4 -0
  191. package/dist/tooling/cli/development/project-imports.d.ts +22 -0
  192. package/dist/tooling/cli/development/project-imports.js +39 -0
  193. package/dist/tooling/cli/development/project-lock.d.ts +3 -4
  194. package/dist/tooling/cli/development/project-lock.js +14 -166
  195. package/dist/tooling/cli/development/release-evidence.d.ts +4 -0
  196. package/dist/tooling/cli/development/release-evidence.js +10 -0
  197. package/dist/tooling/cli/development/report.d.ts +6 -0
  198. package/dist/tooling/cli/development/report.js +14 -0
  199. package/dist/tooling/cli/development/source-watch.js +53 -5
  200. package/dist/tooling/cli/development/sources.d.ts +7 -0
  201. package/dist/tooling/cli/development/sources.js +48 -0
  202. package/dist/tooling/cli/development/target-lock.d.ts +16 -0
  203. package/dist/tooling/cli/development/target-lock.js +68 -0
  204. package/dist/tooling/cli/development/view.d.ts +28 -0
  205. package/dist/tooling/cli/development/view.js +151 -0
  206. package/dist/tooling/cli/environment-release.d.ts +21 -0
  207. package/dist/tooling/cli/environment-release.js +46 -0
  208. package/dist/tooling/cli/evidence.d.ts +11 -0
  209. package/dist/tooling/cli/evidence.js +53 -0
  210. package/dist/tooling/cli/help.js +78 -34
  211. package/dist/tooling/cli/index.d.ts +1 -1
  212. package/dist/tooling/cli/index.js +1 -1
  213. package/dist/tooling/cli/installation/index.d.ts +2 -0
  214. package/dist/tooling/cli/installation/index.js +1 -0
  215. package/dist/tooling/cli/installation/observation.d.ts +10 -0
  216. package/dist/tooling/cli/installation/observation.js +44 -0
  217. package/dist/tooling/cli/installation/reconcile.d.ts +32 -0
  218. package/dist/tooling/cli/installation/reconcile.js +122 -0
  219. package/dist/tooling/cli/orchestrate.js +84 -44
  220. package/dist/tooling/cli/project.d.ts +17 -0
  221. package/dist/tooling/cli/project.js +18 -0
  222. package/dist/tooling/cli/test.d.ts +12 -0
  223. package/dist/tooling/cli/test.js +47 -0
  224. package/dist/tooling/cli/upgrade/index.d.ts +6 -0
  225. package/dist/tooling/cli/upgrade/index.js +115 -0
  226. package/dist/tooling/cli/upgrade/manifest.d.ts +18 -0
  227. package/dist/tooling/cli/upgrade/manifest.js +77 -0
  228. package/dist/tooling/cli/upgrade/process.d.ts +2 -0
  229. package/dist/tooling/cli/upgrade/process.js +57 -0
  230. package/dist/tooling/linter/adapters/typescript/imports.js +2 -0
  231. package/dist/tooling/linter/adapters/typescript/index.d.ts +1 -0
  232. package/dist/tooling/linter/adapters/typescript/index.js +1 -0
  233. package/dist/tooling/linter/adapters/typescript/query-collection-type.js +4 -51
  234. package/dist/tooling/linter/adapters/typescript/type-analysis.d.ts +9 -0
  235. package/dist/tooling/linter/adapters/typescript/type-analysis.js +55 -0
  236. package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +28 -0
  237. package/dist/tooling/linter/implementations/source/callable-requirements.js +234 -0
  238. package/dist/tooling/linter/implementations/source/dependencies.d.ts +2 -0
  239. package/dist/tooling/linter/implementations/source/dependencies.js +219 -0
  240. package/dist/tooling/linter/implementations/source/global.js +52 -2
  241. package/dist/tooling/linter/implementations/source/mutations.js +520 -38
  242. package/dist/tooling/linter/implementations/source/providers.js +19 -164
  243. package/dist/tooling/linter/implementations/source/schema.js +454 -2
  244. package/dist/tooling/linter/implementations/source/verifiers.js +2 -0
  245. package/dist/tooling/linter/implementations/source/workflows.js +8 -35
  246. package/dist/tooling/linter/policy/generated.js +2 -2
  247. package/dist/tooling/linter/requirements/registry.js +9 -3
  248. package/dist/tooling/packaging/declarations/normalize.js +3 -38
  249. package/dist/tooling/packaging/declarations/paths.d.ts +5 -0
  250. package/dist/tooling/packaging/declarations/paths.js +38 -0
  251. package/dist/tooling/packaging/finalize.d.ts +13 -0
  252. package/dist/tooling/packaging/finalize.js +62 -0
  253. package/dist/tooling/packaging/index.d.ts +2 -0
  254. package/dist/tooling/packaging/index.js +1 -0
  255. package/dist/tooling/packaging/javascript.d.ts +3 -0
  256. package/dist/tooling/packaging/javascript.js +45 -2
  257. package/dist/tooling/packaging/packaging.d.ts +2 -5
  258. package/dist/tooling/packaging/packaging.js +6 -30
  259. package/package.json +42 -12
  260. package/CHANGELOG.md +0 -1506
  261. package/dist/deployment/adapter/development/context.d.ts +0 -18
  262. package/dist/deployment/adapter/development/index.d.ts +0 -4
  263. package/dist/deployment/adapter/development/input.d.ts +0 -6
  264. package/dist/deployment/adapter/development/placement.d.ts +0 -15
  265. package/dist/deployment/adapter/development/session.d.ts +0 -9
  266. /package/dist/{deployment/adapter/development → application/dependency}/index.js +0 -0
  267. /package/dist/{deployment/adapter/development/context.js → application/dependency/invoker.js} +0 -0
  268. /package/dist/{deployment/adapter/development/input.js → application/integration/authentication.js} +0 -0
  269. /package/dist/{deployment/adapter/development/placement.js → application/integration/authentication.typecheck.d.ts} +0 -0
  270. /package/dist/{deployment/adapter/development/session.js → application/runtime/declarations.js} +0 -0
package/README.md CHANGED
@@ -31,12 +31,117 @@ npx -y create-astrale-domain@beta my-domain --yes
31
31
  See [the release lifecycle](docs/release.md) for package-set versioning, verification, and stable
32
32
  promotion.
33
33
 
34
+ ### Update a pnpm project
35
+
36
+ ```sh
37
+ pnpm exec astrale-domain upgrade --check # Preview; no project changes
38
+ pnpm exec astrale-domain upgrade # Update existing Astrale dependencies to beta
39
+ ```
40
+
41
+ The command covers the workspace root and its packages, pins exact versions, and updates the
42
+ lockfile through pnpm. Use `--channel latest` to select that tag instead. Missing tags and local,
43
+ catalog, or aliased dependencies are left unchanged and reported; peers and overrides are not edited.
44
+ For an older SDK without this command, start with `pnpm dlx @astrale-os/sdk@beta upgrade`.
45
+ Stop development watchers first, then run the project's checks and validate on development.
46
+ Nothing is committed or deployed. A Shell update also requires checking the installed Shell revision.
47
+ Rerunning an upgrade synchronizes installation even when the manifest versions are already current.
48
+
49
+ ## Move a runtime without changing its Domain identity
50
+
51
+ A Domain issuer is retained across installation upgrades. To deploy a new Cloudflare runtime for
52
+ selected instances, keep the existing signing identity and issuer while selecting a new public origin:
53
+
54
+ ```ts
55
+ cloudflare({
56
+ route: 'services-v2.example.com',
57
+ workerName: 'services-v2',
58
+ identityIssuer: 'https://services.example.com',
59
+ signingIdentity: '.astrale/identity.json',
60
+ })
61
+ ```
62
+
63
+ The new Publication places its Bundle, Delivery, callables, Views and routes at the new origin.
64
+ Install that public URL on each intended instance. The Kernel verifies its Delivery against the
65
+ retained issuer's keys and preserves the Domain installation identity and owned data. Keep the
66
+ original issuer discovery endpoints and keys available; unadopted instances continue to use their
67
+ previous bindings. Deployment readiness checks the exact new Worker version separately from issuer
68
+ discovery. No uninstall or identity rotation is involved.
69
+
70
+ At the provider-neutral release boundary, use
71
+ `addressing('https://services.example.com', { publicUrl: 'https://services-v2.example.com' })`.
72
+ The one-argument form continues to use the issuer as the public URL.
73
+
74
+ ## Handler authority and dependencies
75
+
76
+ Authenticated handlers use Domain self authority for `kernel`, `graph`, `query`, and `mutate`.
77
+ `dependencies.directory.invoke(d => d.functions.lookup, input)` calls a direct declared dependency
78
+ with the incoming caller Grant. Explicit authority remains on `kernel` and `graph`; the former
79
+ handler `client` is removed. See [the API and migration guide](docs/handler-dependencies.md).
80
+
81
+ ## Node Class icons
82
+
83
+ Every Node Class authored through the SDK must explicitly declare a self-contained SVG icon.
84
+ Omission is rejected by TypeScript, at the runtime authoring boundary, and by the
85
+ `SCH-ICON-REQUIRED` linter rule. Prefer framework-neutral Lucide data when an icon exists in that
86
+ catalog:
87
+
88
+ ```typescript
89
+ import { classIcon, nodeClass } from '@astrale-os/sdk/schema'
90
+ import { FileText } from '@astrale-os/sdk/schema/icons'
91
+
92
+ export const Article = nodeClass({
93
+ icon: classIcon.lucide(FileText),
94
+ })
95
+ ```
96
+
97
+ Use `classIcon.svg(source)` for a custom self-contained SVG. If no meaningful icon has been chosen,
98
+ declare `icon: classIcon.neutral` explicitly. This stable empty SVG renders no glyph and remains
99
+ valid; the linter emits a non-failing `SCH-ICON-NEUTRAL` warning. Bare names such as `"file-text"`,
100
+ non-canonical empty SVGs, external references, and executable SVG content are rejected during
101
+ Schema authoring.
102
+
103
+ ## Business-error declarations
104
+
105
+ Declare reusable business errors in `schema/modules/<module>/errors/` through the Schema facade:
106
+
107
+ ```typescript
108
+ import { error } from '@astrale-os/sdk/schema/errors'
109
+ import { z } from 'zod'
110
+
111
+ export const resourceUnavailable = error({
112
+ family: 'NOT_FOUND',
113
+ message: 'The selected resource is unavailable.',
114
+ details: z.strictObject({ resource: z.string() }),
115
+ })
116
+ ```
117
+
118
+ Register the declaration under a code in an Action or Workflow's options:
119
+ `{ errors: { RESOURCE_UNAVAILABLE: resourceUnavailable } }`. Its handler can then
120
+ `throw error('RESOURCE_UNAVAILABLE', { resource: id })` using the context factory.
121
+ The builder validates and freezes declaration metadata while preserving exact details inference.
122
+ Use `sdk/schema/errors` for declarations shared with handlers: this narrow entrypoint keeps the
123
+ Schema compiler and Kernel Schema initialization out of the deployed Runtime.
124
+ Error declarations are not yet published in the installed Kernel Schema.
125
+
34
126
  ## Development
35
127
 
128
+ ### Core Identity requirements
129
+
130
+ Use `requirements({ core: [{ subject, functions, classes, authority }] })` to declare capabilities
131
+ for an Identity in the Application's local Core. `subject` is the resolved Core Node; each entry
132
+ must request at least one capability. The top-level `functions`, `classes`, and `authority` members
133
+ describe capabilities for the Domain principal.
134
+
135
+ This replaces `requirements.profiles`. Rename that property to `core` and imported
136
+ `CapabilityProfileRequirement` / `CapabilityProfileRequirementInput` types to `CoreRequirement` /
137
+ `CoreRequirementInput`. Builds emit `requirements.capabilities.core`; new releases use Publication
138
+ v3 and require a Kernel that supports it. That Kernel can restore historical v2 Publications and
139
+ installation ledgers without changing their existing authority or integrity evidence.
140
+
36
141
  ### Prerequisites
37
142
 
38
143
  - Node.js 26.7.0 (default) or Node.js 24; published packages remain compatible with Node.js 22+
39
- - pnpm 12.0.0
144
+ - pnpm 12.1.0
40
145
 
41
146
  ### Setup
42
147
 
@@ -45,9 +150,11 @@ The repository installs autonomously from its versioned npm-only lockfile:
45
150
  ```bash
46
151
  git clone https://github.com/astrale-os/sdk.git
47
152
  cd sdk
48
- STANDALONE=true pnpm install --frozen-lockfile
153
+ AGENT_HARNESSES=codex bash scripts/setup/setup.sh
49
154
  ```
50
155
 
156
+ See [agent setup](scripts/setup/README.md) for Claude Cloud and validation.
157
+
51
158
  It can also be consumed as a submodule of the main Astrale workspace:
52
159
 
53
160
  ```bash
@@ -109,6 +216,62 @@ linter tool failures.
109
216
  Structured review [issues](issues/README.md) retain observation-first evidence and later governance
110
217
  attachments without becoming current contract authority.
111
218
 
219
+ ## Dataset references
220
+
221
+ A Dataset can materialize a projected Node explicitly with `ref`, using its resolved local or
222
+ direct-dependency definition:
223
+
224
+ ```typescript
225
+ const demo = defineDataset(Schema, {
226
+ id: 'demo',
227
+ graph({ domain, ref }) {
228
+ const member = ref(domain.core.nodes.member)
229
+ // Repeating ref returns the same Dataset Node. node() always creates a separate identity.
230
+ return { member }
231
+ },
232
+ })
233
+ ```
234
+
235
+ `ref` uses the canonical symbolic Schema projection for Class, Function, Policy, View and Core
236
+ facts. The Dataset's `references` table retains the explicit association between each projected
237
+ NodePath and its Dataset Node ID through encoding and decoding. Matching properties or slugs do
238
+ not create that association. Studio uses it when simulating `sameNode` and reference endpoints;
239
+ a missing association makes that simulation unavailable.
240
+
241
+ ## Kernel publication discovery
242
+
243
+ Use `session.publication()` when a consumer needs the intrinsic Kernel's published identity or
244
+ endpoints without its schema bundle or Views. It revalidates through the Client's existing issuer,
245
+ URL, size, and ETag checks. Concurrent publication and snapshot observations share acquisition;
246
+ cancelling one observer does not cancel another. `session.snapshot()` remains the complete,
247
+ coherent Publication, bundle, and View catalog observation.
248
+
112
249
  ## License
113
250
 
114
251
  Apache License 2.0 — see [LICENSE](LICENSE) for details.
252
+
253
+ ## View host requirements
254
+
255
+ A frontend route can declare the exact external origins its View needs to open:
256
+
257
+ ```ts
258
+ routes: {
259
+ application: {
260
+ path: '/',
261
+ host: {
262
+ navigation: {
263
+ external: { origins: ['https://provider.example'] },
264
+ },
265
+ },
266
+ },
267
+ }
268
+ ```
269
+
270
+ These requirements are publication metadata, so changing them updates the publication ETag without
271
+ changing the Application's business Schema. They require the `shell` handshake. Origins must use
272
+ HTTPS without credentials, paths, queries, fragments, or wildcards; authoring normalizes and sorts
273
+ them. Supporting hosts admit them per mount and execute the existing `browser.openExternal`
274
+ intent. Nested Views cannot expand their parent's grant.
275
+
276
+ For the unified authentication facade and coordinated consumer update, see
277
+ [the Auth API migration guide](docs/auth-api-migration.md).
@@ -1,4 +1,5 @@
1
1
  import type { Domain, ResolvedMethod, schema } from '../../platform/schema/index.js';
2
+ import type { DeclaredErrors, NoDeclaredErrors } from '../error/index.js';
2
3
  import type { Integrations } from '../integration/index.js';
3
4
  import type { ActionContext, ResolvedCallable } from './context.js';
4
5
  import type { ActionOutputOf } from './output.js';
@@ -15,7 +16,9 @@ type MethodValues<Class> = Class extends {
15
16
  };
16
17
  };
17
18
  } ? Values<Instance> | Values<Static> : never;
18
- type Executable<Callable> = Callable extends ResolvedMethod<unknown, unknown, boolean, infer Inheritance> ? Inheritance extends 'abstract' ? never : Callable : Callable;
19
+ type Executable<Callable> = Callable extends ResolvedMethod ? Callable extends {
20
+ readonly executable: true;
21
+ } ? Callable : never : Callable;
19
22
  /** Every root-owned callable implementation contract, independent of Function or Method topology. */
20
23
  export type LocalCallable<DomainValue extends Domain> = Extract<Values<DomainValue['functions']>, ResolvedCallable> | Extract<Executable<MethodValues<Values<DomainValue['classes']>>>, ResolvedCallable>;
21
24
  export type ActionAddressOf<Callable> = Callable extends {
@@ -27,13 +30,13 @@ export type ResolvedDomainOf<Schema extends schema.DomainSchema> = Extract<schem
27
30
  /** SDK Action address derived mechanically from the canonical local callable key. */
28
31
  export type ActionAddress<Schema extends schema.DomainSchema> = ActionAddressOf<LocalCallable<ResolvedDomainOf<Schema>>>;
29
32
  export type CallableAtAddress<Schema extends schema.DomainSchema, Address extends string> = LocalCallable<ResolvedDomainOf<Schema>> extends infer Callable ? Callable extends unknown ? ActionAddressOf<Callable> extends Address ? Callable : never : never : never;
30
- export type Action<Callable extends ResolvedCallable, Definitions extends Integrations = Readonly<Record<never, never>>, DomainValue extends Domain = Domain> = (context: ActionContext<Callable, DomainValue, Definitions>) => Promise<ActionOutputOf<Callable>>;
33
+ export type Action<Callable extends ResolvedCallable, Definitions extends Integrations = Readonly<Record<never, never>>, DomainValue extends Domain = Domain, Errors extends DeclaredErrors = NoDeclaredErrors> = (context: ActionContext<Callable, DomainValue, Definitions, Errors>) => Promise<ActionOutputOf<Callable>>;
31
34
  declare const ACTION_SCHEMA: unique symbol;
32
35
  /** Sealed standalone Action awaiting canonical callable association by Runtime admission. */
33
- export interface ActionDefinition<Schema extends schema.DomainSchema = schema.DomainSchema, Address extends ActionAddress<Schema> = ActionAddress<Schema>, Definitions extends Integrations = Readonly<Record<never, never>>> {
36
+ export interface ActionDefinition<Schema extends schema.DomainSchema = schema.DomainSchema, Address extends ActionAddress<Schema> = ActionAddress<Schema>, Definitions extends Integrations = Readonly<Record<never, never>>, Errors extends DeclaredErrors = NoDeclaredErrors> {
34
37
  readonly kind: 'action';
35
38
  readonly address: Address;
36
- readonly run: Action<Extract<CallableAtAddress<Schema, Address>, ResolvedCallable>, Definitions, ResolvedDomainOf<Schema>>;
39
+ readonly run: Action<Extract<CallableAtAddress<Schema, Address>, ResolvedCallable>, Definitions, ResolvedDomainOf<Schema>, Errors>;
37
40
  /** Invariant type-only Schema witness; absent from emitted JavaScript. */
38
41
  readonly [ACTION_SCHEMA]: (schema: Schema) => Schema;
39
42
  }
@@ -1,4 +1,5 @@
1
1
  export { defineAction } from './define.js';
2
2
  export type { Action, ActionDefinition } from './action.js';
3
- export type { ActionContext, ActionExecution, Caller, DomainGraphExecutor, DomainGraphExecutors, } from './context.js';
3
+ export type { ActionContext, ActionExecution, Caller, DomainGraphExecutor, DomainGraphExecutors, DomainKernelSessions, } from './context.js';
4
4
  export type { ActionBinary, ActionOutputOf } from './output.js';
5
+ export type { DeclaredErrorDefinition, DeclaredErrorFactory, DeclaredErrorFamily, DeclaredErrorOptions, DeclaredErrors, } from '../error/index.js';
@@ -2,6 +2,8 @@ import type { AuthenticationEvidence, Grant, IdentityId } from '../../platform/a
2
2
  import type { BoundClientSession } from '../../platform/client/session/index.js';
3
3
  import type { NodeId } from '../../platform/graph/node/index.js';
4
4
  import type { CallableInputOf, Domain, ResolvedFunction, ResolvedMethod } from '../../platform/schema/index.js';
5
+ import type { HandlerDependencies } from '../dependency/index.js';
6
+ import type { DeclaredErrorFactory, DeclaredErrors, NoDeclaredErrors } from '../error/index.js';
5
7
  import type { IntegrationClients, Integrations } from '../integration/index.js';
6
8
  import type { MutationExecutor } from '../mutation/index.js';
7
9
  import type { QueryExecutor } from '../query/index.js';
@@ -9,6 +11,9 @@ export type ResolvedCallable = ResolvedFunction | ResolvedMethod;
9
11
  /** Bearer-free caller evidence established before an Action or Workflow runs. */
10
12
  export interface AuthenticatedCaller {
11
13
  readonly kind: 'authenticated';
14
+ /** Exact effective caller Identity. Access fails when authority is compound. */
15
+ readonly identity: IdentityId;
16
+ /** Identity whose credential directly authenticated this invocation. */
12
17
  readonly principal: IdentityId;
13
18
  readonly authority: Grant;
14
19
  readonly authentication: AuthenticationEvidence;
@@ -33,37 +38,35 @@ export interface DomainGraphExecutor<DomainValue extends Domain = Domain> {
33
38
  readonly query: QueryExecutor<DomainValue>;
34
39
  readonly mutate: MutationExecutor<DomainValue>;
35
40
  }
36
- export type DomainGraphExecutors<DomainValue extends Domain = Domain> = Readonly<Record<'caller' | 'self' | 'union', DomainGraphExecutor<DomainValue>>>;
37
- /** Explicit full Kernel sessions. No authority mode is selected implicitly. */
38
- export type DomainKernelSessions = Readonly<Record<'caller' | 'self' | 'union', BoundClientSession>>;
41
+ export type DomainGraphExecutors<DomainValue extends Domain = Domain> = Readonly<DomainGraphExecutor<DomainValue> & Record<'caller' | 'self' | 'union', DomainGraphExecutor<DomainValue>>>;
42
+ /** Self-default Kernel session with one level of explicit authority selection. */
43
+ export type DomainKernelSessions = Readonly<BoundClientSession & Record<'caller' | 'self' | 'union', BoundClientSession>>;
39
44
  type AuthorityOf<Callable, DomainValue extends Domain> = Callable extends {
40
45
  readonly auth: 'anonymous';
41
46
  } ? {
42
47
  readonly caller: AnonymousCaller;
43
- readonly client: null;
48
+ readonly dependencies: null;
44
49
  readonly kernel: null;
45
50
  readonly graph: null;
46
51
  readonly query?: never;
47
52
  readonly mutate?: never;
48
53
  } | {
49
54
  readonly caller: AuthenticatedCaller;
50
- /** Caller-only Kernel client. Privileged Domain work must select kernel.self explicitly. */
51
- readonly client: BoundClientSession;
55
+ readonly dependencies: HandlerDependencies<DomainValue>;
52
56
  readonly kernel: DomainKernelSessions;
53
57
  readonly graph: DomainGraphExecutors<DomainValue>;
54
- /** Caller-only convenience executor. */
58
+ /** Convenience executor using the installed Domain authority (`graph.self`). */
55
59
  readonly query: QueryExecutor<DomainValue>;
56
- /** Caller-only convenience executor. */
60
+ /** Convenience executor using the installed Domain authority (`graph.self`). */
57
61
  readonly mutate: MutationExecutor<DomainValue>;
58
62
  } : {
59
63
  readonly caller: AuthenticatedCaller;
60
- /** Caller-only Kernel client. Privileged Domain work must select kernel.self explicitly. */
61
- readonly client: BoundClientSession;
64
+ readonly dependencies: HandlerDependencies<DomainValue>;
62
65
  readonly kernel: DomainKernelSessions;
63
66
  readonly graph: DomainGraphExecutors<DomainValue>;
64
- /** Caller-only convenience executor. */
67
+ /** Convenience executor using the installed Domain authority (`graph.self`). */
65
68
  readonly query: QueryExecutor<DomainValue>;
66
- /** Caller-only convenience executor. */
69
+ /** Convenience executor using the installed Domain authority (`graph.self`). */
67
70
  readonly mutate: MutationExecutor<DomainValue>;
68
71
  };
69
72
  type SelfOf<Callable> = Callable extends ResolvedMethod<unknown, unknown, false> ? {
@@ -72,11 +75,13 @@ type SelfOf<Callable> = Callable extends ResolvedMethod<unknown, unknown, false>
72
75
  readonly self?: never;
73
76
  };
74
77
  /** Exact single-step Action context derived from one resolved callable. */
75
- export type ActionContext<Callable extends ResolvedCallable, DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>> = {
78
+ export type ActionContext<Callable extends ResolvedCallable, DomainValue extends Domain = Domain, Definitions extends Integrations = Readonly<Record<never, never>>, Errors extends DeclaredErrors = NoDeclaredErrors> = {
76
79
  /** Exact admitted Domain retained by the Build being executed. */
77
80
  readonly domain: DomainValue;
78
81
  readonly input: CallableInputOf<Callable>;
79
82
  readonly integrations: IntegrationClients<Definitions>;
80
83
  readonly execution: ActionExecution;
84
+ /** Construct one implementation-declared safe business error for `throw error(...)`. */
85
+ readonly error: DeclaredErrorFactory<Errors>;
81
86
  } & AuthorityOf<Callable, DomainValue> & SelfOf<Callable>;
82
87
  export {};
@@ -1,8 +1,12 @@
1
1
  import type { schema } from '../../platform/schema/index.js';
2
+ import type { DeclaredErrorOptions, DeclaredErrors, NoDeclaredErrors } from '../error/index.js';
2
3
  import type { Integrations } from '../integration/index.js';
3
4
  import type { Action, ActionAddress, ActionDefinition, CallableAtAddress, ResolvedDomainOf } from './action.js';
4
5
  import type { ResolvedCallable } from './context.js';
5
6
  /** Define one simple single-step implementation by its SDK Action address. */
6
- export declare function defineAction<Schema extends schema.DomainSchema, Definitions extends Integrations = Readonly<Record<never, never>>>(): <const Address extends ActionAddress<Schema>>(address: Address, run: Action<Extract<CallableAtAddress<Schema, Address>, ResolvedCallable>, Definitions, ResolvedDomainOf<Schema>>) => ActionDefinition<Schema, Address, Definitions>;
7
+ export declare function defineAction<Schema extends schema.DomainSchema, Definitions extends Integrations = Readonly<Record<never, never>>>(): {
8
+ <const Address extends ActionAddress<Schema>>(address: Address, run: Action<Extract<CallableAtAddress<Schema, Address>, ResolvedCallable>, Definitions, ResolvedDomainOf<Schema>, NoDeclaredErrors>): ActionDefinition<Schema, Address, Definitions, NoDeclaredErrors>;
9
+ <const Address extends ActionAddress<Schema>, const Errors extends DeclaredErrors>(address: Address, options: DeclaredErrorOptions<Errors>, run: Action<Extract<CallableAtAddress<Schema, Address>, ResolvedCallable>, Definitions, ResolvedDomainOf<Schema>, Errors>): ActionDefinition<Schema, Address, Definitions, Errors>;
10
+ };
7
11
  /** True only for an Action produced by defineAction in this SDK package root. */
8
12
  export declare function isAction(input: unknown): input is ActionDefinition;
@@ -1,12 +1,17 @@
1
1
  import { patterns } from '@astrale-os/kernel-dsl/v1/addressing';
2
+ import { rememberDeclaredErrors } from '../error/index.js';
2
3
  const admittedActions = new WeakSet();
3
4
  /** Define one simple single-step implementation by its SDK Action address. */
4
5
  export function defineAction() {
5
- return function define(address, run) {
6
+ return function define(address, optionsOrRun, possibleRun) {
6
7
  acceptActionAddress(address);
8
+ const options = possibleRun === undefined ? undefined : optionsOrRun;
9
+ const run = possibleRun ?? optionsOrRun;
7
10
  if (typeof run !== 'function')
8
11
  throw new TypeError('Action run must be a function.');
9
12
  const action = Object.freeze({ kind: 'action', address, run });
13
+ if (options !== undefined)
14
+ rememberDeclaredErrors(action, options);
10
15
  admittedActions.add(action);
11
16
  return action;
12
17
  };
@@ -1,4 +1,5 @@
1
1
  export { defineAction, isAction } from './define.js';
2
2
  export type { Action, ActionAddress, ActionAddressOf, ActionDefinition, CallableAtAddress, LocalCallable, ResolvedDomainOf, } from './action.js';
3
- export type { ActionContext, ActionExecution, AnonymousCaller, AuthenticatedCaller, Caller, DomainGraphExecutor, DomainGraphExecutors, ResolvedCallable, } from './context.js';
3
+ export type { ActionContext, ActionExecution, AnonymousCaller, AuthenticatedCaller, Caller, DomainGraphExecutor, DomainGraphExecutors, DomainKernelSessions, ResolvedCallable, } from './context.js';
4
4
  export type { ActionBinary, ActionOutputOf } from './output.js';
5
+ export type { DeclaredErrorDefinition, DeclaredErrorFactory, DeclaredErrorFamily, DeclaredErrorOptions, DeclaredErrors, } from '../error/index.js';
@@ -0,0 +1 @@
1
+ export type { DependencyCallOptions, DependencyInvoker, HandlerDependencies } from './invoker.js';
@@ -0,0 +1,26 @@
1
+ import type { Binary, Input } from '../../platform/client/index.js';
2
+ import type { SessionRequestOptions } from '../../platform/client/session/index.js';
3
+ import type { NodeId } from '../../platform/graph/node/index.js';
4
+ import type { CallableInputOf, CallableOutputOf, CallableResultOf, Domain, ResolvedMethod, KernelSchema, schema } from '../../platform/schema/index.js';
5
+ import type { LocalCallable } from '../action/index.js';
6
+ export type DependencyCallOptions = Pick<SessionRequestOptions, 'timeoutMs' | 'idempotencyKey'>;
7
+ type InstanceMethodOf<D extends Domain> = Extract<LocalCallable<D>, ResolvedMethod<unknown, unknown, false>>;
8
+ type FunctionOrStaticMethodOf<D extends Domain> = Exclude<LocalCallable<D>, ResolvedMethod<unknown, unknown, false>>;
9
+ type DependencyInputOf<C> = C extends unknown ? unknown extends CallableInputOf<C> ? Input : [CallableInputOf<C>] extends [void] ? undefined : CallableInputOf<C> : never;
10
+ type DependencyResultOf<C> = unknown extends CallableOutputOf<C> ? unknown : CallableResultOf<C, Binary>;
11
+ /** One declared dependency, bound to one explicitly selected invocation authority. */
12
+ export interface DependencyInvoker<D extends Domain> {
13
+ readonly invoke: {
14
+ <const C extends FunctionOrStaticMethodOf<D>>(select: (domain: D) => C, input: NoInfer<DependencyInputOf<C>>, options?: DependencyCallOptions): Promise<DependencyResultOf<C>>;
15
+ <const C extends InstanceMethodOf<D>>(select: (domain: D) => C, instance: NodeId, input: NoInfer<DependencyInputOf<C>>, options?: DependencyCallOptions): Promise<DependencyResultOf<C>>;
16
+ };
17
+ }
18
+ /**
19
+ * Direct Schema aliases with explicit authority selection and no default invoke.
20
+ * self is the executing Domain; caller forwards the incoming Grant; union combines both.
21
+ * The canonical Kernel is exposed through context.kernel.
22
+ */
23
+ export type HandlerDependencies<D extends Domain> = Readonly<{
24
+ [Alias in keyof D['dependencies'] as D['dependencies'][Alias] extends schema.DomainOf<KernelSchema> ? never : Alias]: Readonly<Record<'caller' | 'self' | 'union', DependencyInvoker<Extract<D['dependencies'][Alias], Domain>>>>;
25
+ }>;
26
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { z } from 'zod';
2
+ import type { DeclaredErrorDefinition } from '../../platform/schema/error.js';
3
+ import * as value from '../../platform/value/index.js';
4
+ export type { DeclaredErrorDefinition, DeclaredErrorFamily } from '../../platform/schema/error.js';
5
+ export type DeclaredErrors = Readonly<Record<string, DeclaredErrorDefinition>>;
6
+ export type NoDeclaredErrors = Readonly<Record<never, never>>;
7
+ export interface DeclaredErrorOptions<out Errors extends DeclaredErrors = DeclaredErrors> {
8
+ readonly errors: Errors;
9
+ }
10
+ export type DeclaredErrorFactory<Errors extends DeclaredErrors> = <Code extends Extract<keyof Errors, string>>(code: Code, details: z.input<Errors[Code]['details']>) => Error;
11
+ interface DeclaredErrorRecord {
12
+ readonly definition: object;
13
+ readonly code: string;
14
+ readonly family: DeclaredErrorDefinition['family'];
15
+ readonly message: string;
16
+ readonly details: value.Object;
17
+ }
18
+ /** Retain one implementation-local expected-error contract without publishing it in the Schema. */
19
+ export declare function rememberDeclaredErrors(definition: object, input: unknown): void;
20
+ /** Create a receiver-free factory closed over one admitted Action or Workflow definition. */
21
+ export declare function declaredErrorFactory<Errors extends DeclaredErrors>(definition: object): DeclaredErrorFactory<Errors>;
22
+ /** Return admitted evidence only when the error belongs to the active implementation. */
23
+ export declare function declaredErrorOf(input: unknown, definition: object): DeclaredErrorRecord | undefined;
@@ -0,0 +1,87 @@
1
+ import { acceptErrorDefinition } from '../../platform/schema/error.js';
2
+ import * as value from '../../platform/value/index.js';
3
+ const MAXIMUM_DECLARED_ERRORS = 32;
4
+ const MAXIMUM_DETAILS_BYTES = 16 * 1024;
5
+ const CODE_PATTERN = /^[A-Z][A-Z0-9_]{0,127}$/u;
6
+ const declarations = new WeakMap();
7
+ const errors = new WeakMap();
8
+ class BusinessError extends Error {
9
+ name = 'BusinessError';
10
+ constructor(code) {
11
+ super(`Declared business error ${code}.`);
12
+ }
13
+ }
14
+ /** Retain one implementation-local expected-error contract without publishing it in the Schema. */
15
+ export function rememberDeclaredErrors(definition, input) {
16
+ if (!isRecord(input) || Reflect.ownKeys(input).some((key) => key !== 'errors'))
17
+ invalidOptions();
18
+ if (!isRecord(input.errors))
19
+ invalidOptions();
20
+ const entries = Object.entries(input.errors);
21
+ if (entries.length > MAXIMUM_DECLARED_ERRORS) {
22
+ throw new TypeError(`An implementation may declare at most ${MAXIMUM_DECLARED_ERRORS} errors.`);
23
+ }
24
+ const accepted = new Map();
25
+ for (const [code, candidate] of entries) {
26
+ if (!CODE_PATTERN.test(code))
27
+ throw new TypeError(`Declared error code ${JSON.stringify(code)} is invalid.`);
28
+ accepted.set(code, acceptErrorDefinition(candidate, `Declared error ${JSON.stringify(code)}`));
29
+ }
30
+ declarations.set(definition, accepted);
31
+ }
32
+ /** Create a receiver-free factory closed over one admitted Action or Workflow definition. */
33
+ export function declaredErrorFactory(definition) {
34
+ return ((code, input) => {
35
+ const declaration = declarations.get(definition)?.get(code);
36
+ if (declaration === undefined) {
37
+ throw new TypeError(`Business error ${JSON.stringify(code)} is not declared by this implementation.`);
38
+ }
39
+ const parsed = declaration.details.safeParse(input);
40
+ if (!parsed.success) {
41
+ throw new TypeError(`Business error ${code} details are invalid.`, { cause: parsed.error });
42
+ }
43
+ let details;
44
+ try {
45
+ const accepted = value.accept(parsed.data, { limits: { maxBytes: MAXIMUM_DETAILS_BYTES } });
46
+ value.json.encode(accepted, { limits: { maxBytes: MAXIMUM_DETAILS_BYTES } });
47
+ if (!isRecord(accepted))
48
+ throw new TypeError('Details must be an object.');
49
+ details = freezeValue(accepted);
50
+ }
51
+ catch (cause) {
52
+ throw new TypeError(`Business error ${code} details must be a bounded portable object.`, {
53
+ cause,
54
+ });
55
+ }
56
+ const error = new BusinessError(code);
57
+ errors.set(error, Object.freeze({
58
+ definition,
59
+ code,
60
+ family: declaration.family,
61
+ message: declaration.message,
62
+ details,
63
+ }));
64
+ return error;
65
+ });
66
+ }
67
+ /** Return admitted evidence only when the error belongs to the active implementation. */
68
+ export function declaredErrorOf(input, definition) {
69
+ if (!(input instanceof Error))
70
+ return undefined;
71
+ const record = errors.get(input);
72
+ return record?.definition === definition ? record : undefined;
73
+ }
74
+ function isRecord(input) {
75
+ return input !== null && typeof input === 'object' && !Array.isArray(input);
76
+ }
77
+ function freezeValue(input) {
78
+ return Object.freeze(Object.fromEntries(Object.entries(input).map(([key, nested]) => [key, freezeNestedValue(nested)])));
79
+ }
80
+ function freezeNestedValue(input) {
81
+ if (Array.isArray(input))
82
+ return Object.freeze(input.map(freezeNestedValue));
83
+ return isRecord(input) ? freezeValue(input) : input;
84
+ }
85
+ function invalidOptions() {
86
+ throw new TypeError('Action or Workflow options must contain exactly an errors object.');
87
+ }
@@ -0,0 +1,2 @@
1
+ export type { DeclaredErrorDefinition, DeclaredErrorFactory, DeclaredErrorFamily, DeclaredErrorOptions, DeclaredErrors, NoDeclaredErrors, } from './error.js';
2
+ export { declaredErrorFactory, declaredErrorOf, rememberDeclaredErrors } from './error.js';
@@ -0,0 +1 @@
1
+ export { declaredErrorFactory, declaredErrorOf, rememberDeclaredErrors } from './error.js';
@@ -1,9 +1,9 @@
1
1
  export { defineApplication, isApplication } from './define.js';
2
2
  export type { ApplicationInput } from './define.js';
3
3
  export { requirements } from './requirements/index.js';
4
- export type { AuthorityRequirements, AuthorityRequirementsInput, ClassOperation, ClassRequirement, ClassRequirementInput, FunctionRequirementTarget, Requirements, RequirementsInput, } from './requirements/index.js';
4
+ export type { AuthorityRequirements, AuthorityRequirementsInput, ClassOperation, ClassRequirement, ClassRequirementInput, CoreRequirement, CoreRequirementInput, FunctionRequirementTarget, Requirements, RequirementsInput, } from './requirements/index.js';
5
5
  export { route, routes } from './routes/index.js';
6
6
  export type { Route, RouteInput, RouteTarget, Routes } from './routes/index.js';
7
7
  export { defineFrontend, external, vite } from './view/index.js';
8
- export type { Frontend, FrontendInput, FrontendSource, IframeRequirements } from './view/index.js';
8
+ export type { Frontend, FrontendInput, FrontendSource, IframeRequirements, ViewHostRequirements, } from './view/index.js';
9
9
  export type { Application, ApplicationIdentity, RuntimeOfApplication, SchemaOfApplication, SchemaOfRuntime, } from './application.js';
@@ -0,0 +1,10 @@
1
+ import type { MintedCredential } from '../../platform/auth/index.js';
2
+ export interface IntegrationMintInput {
3
+ readonly audience: string;
4
+ /** Maximum requested lifetime, in whole seconds, from 1 through 60. */
5
+ readonly ttlSeconds: number;
6
+ }
7
+ /** Invocation-bound authentication as the executing Domain, never the caller. */
8
+ export interface IntegrationAuthentication {
9
+ mint(input: IntegrationMintInput): Promise<MintedCredential>;
10
+ }
@@ -0,0 +1,18 @@
1
+ async function provider(execution) {
2
+ // @ts-expect-error An anonymous invocation has no auth capability.
3
+ await execution.auth.mint({ audience: 'admin', ttlSeconds: 60 });
4
+ if (execution.auth === undefined)
5
+ return;
6
+ await execution.auth.mint({ audience: 'admin', ttlSeconds: 60 });
7
+ // @ts-expect-error Providers cannot register identities.
8
+ execution.auth.register({});
9
+ // @ts-expect-error Providers cannot delegate authority.
10
+ execution.auth.delegate({});
11
+ // @ts-expect-error Providers cannot supply a Grant.
12
+ execution.auth.mint({ audience: 'admin', ttlSeconds: 60, grant: {} });
13
+ // @ts-expect-error The destination audience is mandatory.
14
+ const invalid = { ttlSeconds: 60 };
15
+ return invalid;
16
+ }
17
+ void provider;
18
+ export {};
@@ -1,4 +1,5 @@
1
1
  import type { BoundClientSession } from '../../platform/client/session/index.js';
2
+ import type { IntegrationAuthentication } from './authentication.js';
2
3
  import type { IntegrationClients, Integrations } from './integration.js';
3
4
  import type { IntegrationReplayDecision } from './operation.js';
4
5
  import type { Providers } from './provider.js';
@@ -7,6 +8,7 @@ export interface IntegrationCallCoordinates {
7
8
  readonly signal: AbortSignal;
8
9
  readonly deadline: number;
9
10
  readonly invoke?: BoundClientSession['invoke'];
11
+ readonly auth?: IntegrationAuthentication;
10
12
  }
11
13
  export interface IntegrationAttempt<Output> {
12
14
  readonly integration: string;
@@ -78,8 +78,12 @@ function admitCoordinates(input) {
78
78
  if (input === null || typeof input !== 'object' || Array.isArray(input))
79
79
  invalidCoordinates();
80
80
  const keys = Reflect.ownKeys(input);
81
- if ((keys.length !== 3 && keys.length !== 4) ||
82
- !keys.every((key) => key === 'callId' || key === 'signal' || key === 'deadline' || key === 'invoke') ||
81
+ if (!['callId', 'signal', 'deadline'].every((key) => Object.hasOwn(input, key)) ||
82
+ !keys.every((key) => key === 'callId' ||
83
+ key === 'signal' ||
84
+ key === 'deadline' ||
85
+ key === 'invoke' ||
86
+ key === 'auth') ||
83
87
  typeof input.callId !== 'string' ||
84
88
  input.callId.length === 0 ||
85
89
  input.callId.trim() !== input.callId ||
@@ -88,13 +92,26 @@ function admitCoordinates(input) {
88
92
  (input.invoke !== undefined && typeof input.invoke !== 'function')) {
89
93
  invalidCoordinates();
90
94
  }
95
+ const auth = input.auth === undefined ? undefined : admitAuthentication(input.auth);
91
96
  return Object.freeze({
92
97
  callId: input.callId,
93
98
  signal: input.signal,
94
99
  deadline: input.deadline,
95
100
  ...(input.invoke === undefined ? {} : { invoke: input.invoke }),
101
+ ...(auth === undefined ? {} : { auth }),
96
102
  });
97
103
  }
104
+ function admitAuthentication(input) {
105
+ if (input === null ||
106
+ typeof input !== 'object' ||
107
+ Array.isArray(input) ||
108
+ Reflect.ownKeys(input).length !== 1 ||
109
+ !Object.hasOwn(input, 'mint') ||
110
+ typeof input.mint !== 'function') {
111
+ invalidCoordinates();
112
+ }
113
+ return Object.freeze({ mint: input.mint.bind(input) });
114
+ }
98
115
  function invalidCoordinates() {
99
116
  throw new TypeError('Integration call coordinates are invalid.');
100
117
  }
@@ -5,3 +5,4 @@ export type { DefineIntegration, ProviderBinding } from './define.js';
5
5
  export type { IntegrationClient, IntegrationClients, IntegrationDefinition, Integrations, } from './integration.js';
6
6
  export type { IntegrationExecution, IntegrationInput, IntegrationOperation, IntegrationOperations, IntegrationOutput, IntegrationReplay, IntegrationReplayDecision, } from './operation.js';
7
7
  export type { Provider, ProviderImplementation, Providers } from './provider.js';
8
+ export type { IntegrationAuthentication, IntegrationMintInput } from './authentication.js';
@@ -1,4 +1,5 @@
1
1
  import type { BoundClientSession } from '../../platform/client/session/index.js';
2
+ import type { IntegrationAuthentication } from './authentication.js';
2
3
  declare const INTEGRATION_OPERATION: unique symbol;
3
4
  export type IntegrationReplayDecision = {
4
5
  readonly kind: 'safe';
@@ -20,6 +21,8 @@ export interface IntegrationExecution {
20
21
  readonly idempotencyKey?: string;
21
22
  /** Exact caller-bound invocation capability; absent for an anonymous invocation. */
22
23
  readonly invoke?: BoundClientSession['invoke'];
24
+ /** Domain-self transport authentication; absent for an anonymous invocation. */
25
+ readonly auth?: IntegrationAuthentication;
23
26
  }
24
27
  export interface IntegrationOperation<Input = unknown, Output = unknown> {
25
28
  readonly replay: IntegrationReplay<Input>;