@ontrails/core 1.0.0-beta.14 → 1.0.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 (314) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +73 -24
  3. package/package.json +11 -4
  4. package/src/activation-provenance.ts +111 -0
  5. package/src/activation-source-compatibility.ts +430 -0
  6. package/src/activation-source-projection.ts +221 -0
  7. package/src/activation-source.ts +91 -0
  8. package/src/blob-ref.ts +51 -0
  9. package/src/branded.ts +1 -1
  10. package/src/context.ts +28 -4
  11. package/src/contour.ts +344 -0
  12. package/src/cross-batch.ts +69 -0
  13. package/src/cross-schema.ts +36 -0
  14. package/src/detours.ts +8 -0
  15. package/src/draft.ts +60 -52
  16. package/src/error-projection.ts +51 -0
  17. package/src/errors.ts +245 -48
  18. package/src/execute.ts +1250 -40
  19. package/src/fire.ts +1169 -0
  20. package/src/index.ts +383 -49
  21. package/src/internal/fork-ctx.ts +69 -0
  22. package/src/layer-projection.ts +192 -0
  23. package/src/layer.ts +81 -0
  24. package/src/observe.ts +361 -0
  25. package/src/path-security.ts +1 -1
  26. package/src/permits.ts +12 -0
  27. package/src/redaction/patterns.ts +6 -3
  28. package/src/resilience.ts +11 -11
  29. package/src/resource-config.ts +792 -0
  30. package/src/resource.ts +175 -0
  31. package/src/result.ts +18 -0
  32. package/src/run.ts +7 -6
  33. package/src/schedule-runtime.ts +689 -0
  34. package/src/schedule.ts +324 -0
  35. package/src/serialization.ts +90 -55
  36. package/src/signal-diagnostics.ts +633 -0
  37. package/src/signal-ref.ts +87 -0
  38. package/src/signal.ts +37 -0
  39. package/src/store/accessor-protocol.ts +56 -0
  40. package/src/store/index.ts +4 -0
  41. package/src/structured-examples.ts +245 -0
  42. package/src/surface-derivation.ts +91 -0
  43. package/src/surface-filter.ts +176 -0
  44. package/src/topo.ts +710 -59
  45. package/src/tracing.ts +345 -0
  46. package/src/trail.ts +347 -33
  47. package/src/trails/derive-trail.ts +842 -0
  48. package/src/trails/index.ts +9 -0
  49. package/src/trails/ingest.ts +138 -0
  50. package/src/{internal/trails-db.ts → trails-db.ts} +50 -31
  51. package/src/transport-error-map.ts +174 -0
  52. package/src/type-utils.ts +17 -2
  53. package/src/types.ts +208 -17
  54. package/src/validate-established-topo.ts +8 -2
  55. package/src/validate-topo.ts +244 -13
  56. package/src/validation.ts +58 -1
  57. package/src/webhook.ts +276 -0
  58. package/src/workspace.ts +1 -1
  59. package/src/zod-wrappers.ts +72 -0
  60. package/.turbo/turbo-build.log +0 -1
  61. package/.turbo/turbo-lint.log +0 -3
  62. package/.turbo/turbo-typecheck.log +0 -1
  63. package/dist/adapters.d.ts +0 -39
  64. package/dist/adapters.d.ts.map +0 -1
  65. package/dist/adapters.js +0 -2
  66. package/dist/adapters.js.map +0 -1
  67. package/dist/blob-ref.d.ts +0 -20
  68. package/dist/blob-ref.d.ts.map +0 -1
  69. package/dist/blob-ref.js +0 -22
  70. package/dist/blob-ref.js.map +0 -1
  71. package/dist/branded.d.ts +0 -36
  72. package/dist/branded.d.ts.map +0 -1
  73. package/dist/branded.js +0 -89
  74. package/dist/branded.js.map +0 -1
  75. package/dist/collections.d.ts +0 -31
  76. package/dist/collections.d.ts.map +0 -1
  77. package/dist/collections.js +0 -60
  78. package/dist/collections.js.map +0 -1
  79. package/dist/context.d.ts +0 -10
  80. package/dist/context.d.ts.map +0 -1
  81. package/dist/context.js +0 -21
  82. package/dist/context.js.map +0 -1
  83. package/dist/derive.d.ts +0 -44
  84. package/dist/derive.d.ts.map +0 -1
  85. package/dist/derive.js +0 -149
  86. package/dist/derive.js.map +0 -1
  87. package/dist/dispatch.d.ts +0 -27
  88. package/dist/dispatch.d.ts.map +0 -1
  89. package/dist/dispatch.js +0 -34
  90. package/dist/dispatch.js.map +0 -1
  91. package/dist/draft.d.ts +0 -28
  92. package/dist/draft.d.ts.map +0 -1
  93. package/dist/draft.js +0 -156
  94. package/dist/draft.js.map +0 -1
  95. package/dist/errors.d.ts +0 -83
  96. package/dist/errors.d.ts.map +0 -1
  97. package/dist/errors.js +0 -142
  98. package/dist/errors.js.map +0 -1
  99. package/dist/event.d.ts +0 -8
  100. package/dist/event.d.ts.map +0 -1
  101. package/dist/event.js +0 -7
  102. package/dist/event.js.map +0 -1
  103. package/dist/execute.d.ts +0 -35
  104. package/dist/execute.d.ts.map +0 -1
  105. package/dist/execute.js +0 -90
  106. package/dist/execute.js.map +0 -1
  107. package/dist/fetch.d.ts +0 -15
  108. package/dist/fetch.d.ts.map +0 -1
  109. package/dist/fetch.js +0 -102
  110. package/dist/fetch.js.map +0 -1
  111. package/dist/gate.d.ts +0 -17
  112. package/dist/gate.d.ts.map +0 -1
  113. package/dist/gate.js +0 -21
  114. package/dist/gate.js.map +0 -1
  115. package/dist/guards.d.ts +0 -17
  116. package/dist/guards.d.ts.map +0 -1
  117. package/dist/guards.js +0 -25
  118. package/dist/guards.js.map +0 -1
  119. package/dist/health.d.ts +0 -18
  120. package/dist/health.d.ts.map +0 -1
  121. package/dist/health.js +0 -5
  122. package/dist/health.js.map +0 -1
  123. package/dist/index.d.ts +0 -48
  124. package/dist/index.d.ts.map +0 -1
  125. package/dist/index.js +0 -51
  126. package/dist/index.js.map +0 -1
  127. package/dist/internal/topo-saves.d.ts +0 -47
  128. package/dist/internal/topo-saves.d.ts.map +0 -1
  129. package/dist/internal/topo-saves.js +0 -310
  130. package/dist/internal/topo-saves.js.map +0 -1
  131. package/dist/internal/topo-store-read.d.ts +0 -67
  132. package/dist/internal/topo-store-read.d.ts.map +0 -1
  133. package/dist/internal/topo-store-read.js +0 -222
  134. package/dist/internal/topo-store-read.js.map +0 -1
  135. package/dist/internal/topo-store.d.ts +0 -12
  136. package/dist/internal/topo-store.d.ts.map +0 -1
  137. package/dist/internal/topo-store.js +0 -571
  138. package/dist/internal/topo-store.js.map +0 -1
  139. package/dist/internal/trails-db.d.ts +0 -16
  140. package/dist/internal/trails-db.d.ts.map +0 -1
  141. package/dist/internal/trails-db.js +0 -118
  142. package/dist/internal/trails-db.js.map +0 -1
  143. package/dist/job.d.ts +0 -24
  144. package/dist/job.d.ts.map +0 -1
  145. package/dist/job.js +0 -17
  146. package/dist/job.js.map +0 -1
  147. package/dist/layer.d.ts +0 -6
  148. package/dist/layer.d.ts.map +0 -1
  149. package/dist/layer.js +0 -4
  150. package/dist/layer.js.map +0 -1
  151. package/dist/path-security.d.ts +0 -28
  152. package/dist/path-security.d.ts.map +0 -1
  153. package/dist/path-security.js +0 -63
  154. package/dist/path-security.js.map +0 -1
  155. package/dist/patterns/bulk.d.ts +0 -15
  156. package/dist/patterns/bulk.d.ts.map +0 -1
  157. package/dist/patterns/bulk.js +0 -14
  158. package/dist/patterns/bulk.js.map +0 -1
  159. package/dist/patterns/change.d.ts +0 -10
  160. package/dist/patterns/change.d.ts.map +0 -1
  161. package/dist/patterns/change.js +0 -10
  162. package/dist/patterns/change.js.map +0 -1
  163. package/dist/patterns/date-range.d.ts +0 -10
  164. package/dist/patterns/date-range.d.ts.map +0 -1
  165. package/dist/patterns/date-range.js +0 -10
  166. package/dist/patterns/date-range.js.map +0 -1
  167. package/dist/patterns/index.d.ts +0 -9
  168. package/dist/patterns/index.d.ts.map +0 -1
  169. package/dist/patterns/index.js +0 -9
  170. package/dist/patterns/index.js.map +0 -1
  171. package/dist/patterns/pagination.d.ts +0 -18
  172. package/dist/patterns/pagination.d.ts.map +0 -1
  173. package/dist/patterns/pagination.js +0 -18
  174. package/dist/patterns/pagination.js.map +0 -1
  175. package/dist/patterns/progress.d.ts +0 -11
  176. package/dist/patterns/progress.d.ts.map +0 -1
  177. package/dist/patterns/progress.js +0 -11
  178. package/dist/patterns/progress.js.map +0 -1
  179. package/dist/patterns/sorting.d.ts +0 -13
  180. package/dist/patterns/sorting.d.ts.map +0 -1
  181. package/dist/patterns/sorting.js +0 -10
  182. package/dist/patterns/sorting.js.map +0 -1
  183. package/dist/patterns/status.d.ts +0 -15
  184. package/dist/patterns/status.d.ts.map +0 -1
  185. package/dist/patterns/status.js +0 -9
  186. package/dist/patterns/status.js.map +0 -1
  187. package/dist/patterns/timestamps.d.ts +0 -10
  188. package/dist/patterns/timestamps.d.ts.map +0 -1
  189. package/dist/patterns/timestamps.js +0 -10
  190. package/dist/patterns/timestamps.js.map +0 -1
  191. package/dist/provision-config.d.ts +0 -22
  192. package/dist/provision-config.d.ts.map +0 -1
  193. package/dist/provision-config.js +0 -210
  194. package/dist/provision-config.js.map +0 -1
  195. package/dist/provision.d.ts +0 -71
  196. package/dist/provision.d.ts.map +0 -1
  197. package/dist/provision.js +0 -56
  198. package/dist/provision.js.map +0 -1
  199. package/dist/redaction/index.d.ts +0 -4
  200. package/dist/redaction/index.d.ts.map +0 -1
  201. package/dist/redaction/index.js +0 -3
  202. package/dist/redaction/index.js.map +0 -1
  203. package/dist/redaction/patterns.d.ts +0 -9
  204. package/dist/redaction/patterns.d.ts.map +0 -1
  205. package/dist/redaction/patterns.js +0 -39
  206. package/dist/redaction/patterns.js.map +0 -1
  207. package/dist/redaction/redactor.d.ts +0 -27
  208. package/dist/redaction/redactor.d.ts.map +0 -1
  209. package/dist/redaction/redactor.js +0 -89
  210. package/dist/redaction/redactor.js.map +0 -1
  211. package/dist/resilience.d.ts +0 -34
  212. package/dist/resilience.d.ts.map +0 -1
  213. package/dist/resilience.js +0 -164
  214. package/dist/resilience.js.map +0 -1
  215. package/dist/result.d.ts +0 -57
  216. package/dist/result.d.ts.map +0 -1
  217. package/dist/result.js +0 -156
  218. package/dist/result.js.map +0 -1
  219. package/dist/run.d.ts +0 -27
  220. package/dist/run.d.ts.map +0 -1
  221. package/dist/run.js +0 -34
  222. package/dist/run.js.map +0 -1
  223. package/dist/serialization.d.ts +0 -27
  224. package/dist/serialization.d.ts.map +0 -1
  225. package/dist/serialization.js +0 -153
  226. package/dist/serialization.js.map +0 -1
  227. package/dist/service-config.d.ts +0 -22
  228. package/dist/service-config.d.ts.map +0 -1
  229. package/dist/service-config.js +0 -210
  230. package/dist/service-config.js.map +0 -1
  231. package/dist/service.d.ts +0 -71
  232. package/dist/service.d.ts.map +0 -1
  233. package/dist/service.js +0 -56
  234. package/dist/service.js.map +0 -1
  235. package/dist/signal.d.ts +0 -33
  236. package/dist/signal.d.ts.map +0 -1
  237. package/dist/signal.js +0 -17
  238. package/dist/signal.js.map +0 -1
  239. package/dist/topo-store.d.ts +0 -48
  240. package/dist/topo-store.d.ts.map +0 -1
  241. package/dist/topo-store.js +0 -175
  242. package/dist/topo-store.js.map +0 -1
  243. package/dist/topo.d.ts +0 -25
  244. package/dist/topo.d.ts.map +0 -1
  245. package/dist/topo.js +0 -112
  246. package/dist/topo.js.map +0 -1
  247. package/dist/trail.d.ts +0 -96
  248. package/dist/trail.d.ts.map +0 -1
  249. package/dist/trail.js +0 -20
  250. package/dist/trail.js.map +0 -1
  251. package/dist/type-utils.d.ts +0 -24
  252. package/dist/type-utils.d.ts.map +0 -1
  253. package/dist/type-utils.js +0 -12
  254. package/dist/type-utils.js.map +0 -1
  255. package/dist/types.d.ts +0 -71
  256. package/dist/types.d.ts.map +0 -1
  257. package/dist/types.js +0 -3
  258. package/dist/types.js.map +0 -1
  259. package/dist/validate-established-topo.d.ts +0 -76
  260. package/dist/validate-established-topo.d.ts.map +0 -1
  261. package/dist/validate-established-topo.js +0 -43
  262. package/dist/validate-established-topo.js.map +0 -1
  263. package/dist/validate-topo.d.ts +0 -24
  264. package/dist/validate-topo.d.ts.map +0 -1
  265. package/dist/validate-topo.js +0 -176
  266. package/dist/validate-topo.js.map +0 -1
  267. package/dist/validation.d.ts +0 -27
  268. package/dist/validation.d.ts.map +0 -1
  269. package/dist/validation.js +0 -165
  270. package/dist/validation.js.map +0 -1
  271. package/dist/workspace.d.ts +0 -25
  272. package/dist/workspace.d.ts.map +0 -1
  273. package/dist/workspace.js +0 -57
  274. package/dist/workspace.js.map +0 -1
  275. package/src/__tests__/blob-ref.test.ts +0 -103
  276. package/src/__tests__/branded.test.ts +0 -148
  277. package/src/__tests__/collections.test.ts +0 -126
  278. package/src/__tests__/context.test.ts +0 -77
  279. package/src/__tests__/derive.test.ts +0 -260
  280. package/src/__tests__/errors.test.ts +0 -309
  281. package/src/__tests__/execute.test.ts +0 -525
  282. package/src/__tests__/fetch.test.ts +0 -217
  283. package/src/__tests__/gate.test.ts +0 -125
  284. package/src/__tests__/guards.test.ts +0 -102
  285. package/src/__tests__/path-security.test.ts +0 -114
  286. package/src/__tests__/patterns.test.ts +0 -273
  287. package/src/__tests__/redaction.test.ts +0 -244
  288. package/src/__tests__/resilience.test.ts +0 -246
  289. package/src/__tests__/result.test.ts +0 -155
  290. package/src/__tests__/run.test.ts +0 -181
  291. package/src/__tests__/serialization.test.ts +0 -401
  292. package/src/__tests__/service-config.test.ts +0 -228
  293. package/src/__tests__/service.test.ts +0 -197
  294. package/src/__tests__/signal.test.ts +0 -82
  295. package/src/__tests__/topo-store-read.test.ts +0 -251
  296. package/src/__tests__/topo-store.test.ts +0 -469
  297. package/src/__tests__/topo.test.ts +0 -277
  298. package/src/__tests__/trail-permit.test.ts +0 -60
  299. package/src/__tests__/trail.test.ts +0 -261
  300. package/src/__tests__/trails-db.test.ts +0 -191
  301. package/src/__tests__/type-utils.test.ts +0 -90
  302. package/src/__tests__/validate-topo.test.ts +0 -489
  303. package/src/__tests__/validation.test.ts +0 -336
  304. package/src/__tests__/workspace.test.ts +0 -183
  305. package/src/event.ts +0 -15
  306. package/src/gate.ts +0 -44
  307. package/src/internal/topo-saves.ts +0 -429
  308. package/src/internal/topo-store-read.ts +0 -473
  309. package/src/internal/topo-store.ts +0 -1087
  310. package/src/provision-config.ts +0 -373
  311. package/src/provision.ts +0 -148
  312. package/src/topo-store.ts +0 -301
  313. package/tsconfig.json +0 -9
  314. package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,79 @@
1
1
  # @ontrails/core
2
2
 
3
+ ## 1.0.0-beta.16
4
+
5
+ ### Major Changes
6
+
7
+ - 331e3a9: Relocate the topo-store public API from `@ontrails/core` to `@ontrails/topographer` per ADR-0042. Generic `trails-db` helpers (`openReadTrailsDb`, `openWriteTrailsDb`, `ensureSubsystemSchema`, `deriveTrailsDbPath`, `deriveTrailsDir`) stay in core because tracing and other subsystems share them.
8
+
9
+ Breaking pre-1.0 beta change. Update consumer imports:
10
+
11
+ ```diff
12
+ - import { topoStore, createTopoStore, createMockTopoStore, createTopoSnapshot, listTopoSnapshots, pinTopoSnapshot, unpinTopoSnapshot, createStoredTopoSnapshot, getStoredTopoExport, countTopoSnapshots, countPinnedSnapshots, countPrunableSnapshots, pruneUnpinnedSnapshots } from '@ontrails/core';
13
+ + import { topoStore, createTopoStore, createMockTopoStore, createTopoSnapshot, listTopoSnapshots, pinTopoSnapshot, unpinTopoSnapshot } from '@ontrails/topographer';
14
+ + import { createStoredTopoSnapshot, getStoredTopoExport, countTopoSnapshots, countPinnedSnapshots, countPrunableSnapshots, pruneUnpinnedSnapshots } from '@ontrails/topographer/backend-support';
15
+ ```
16
+
17
+ The same root move applies to types `ReadOnlyTopoStore`, `MockTopoStoreSeed`, `TopoSnapshot`, `TopoStoreRef`, `TopoStoreExportRecord`, `TopoStoreResourceRecord`, `TopoStoreTrailRecord`, `TopoStoreTrailDetailRecord`, `CreateTopoSnapshotInput`, and `ListTopoSnapshotsOptions`. The direct DB helper type `StoredTopoExport` moves to `@ontrails/topographer/backend-support`.
18
+
19
+ Core newly exports `activationSourceKey`, `projectActivationSourceDeclaration`, `activationSourceDeclarationSignature`, and the `ActivationSourceProjection` type — these were already used internally and are now part of the public surface so `@ontrails/topographer` (the only consumer that needs them) can import them through normal package channels.
20
+
21
+ - 10eae9a: Migrate the Trails workspace to the documented `.trails/` layout: committed `.lock` files at the workspace root, ignored `cache/` for rebuildable derived data, ignored `state/` for mutable runtime state, and `.trails/config.local.{ts,js}` for local overrides. The default SQLite path is now `.trails/state/trails.db`. Workspace bootstrap creates only `cache/` and `state/` — the legacy `dev/` and `generated/` subdirectories are no longer created. Dev reset cleans both the new `.trails/state/` paths and legacy `.trails/trails.db*` and `.trails/dev/tracing.db*` paths for one cycle. Scaffold and workspace gitignores reflect the new layout.
22
+
23
+ Workspace bootstrap is now owned by a single canonical source in `@ontrails/core`. The package exposes `ensureTrailsWorkspace()`, `WORKSPACE_GITIGNORE_CONTENT`, and `WORKSPACE_GITIGNORE_LINES`. `@ontrails/config` no longer exports its own `ensureWorkspace` (consumers should import from `@ontrails/core`). `trails create` now writes `.trails/.gitignore` during scaffolding so a fresh-scaffolded project's initial commit includes the workspace gitignore (resolves TRL-703).
24
+
25
+ ### Minor Changes
26
+
27
+ - bcdc484: Add an explicit `unmockable: { reason }` resource marker and have testing auto-mock resolution skip intentionally unmockable resources.
28
+ - 4b8d13b: **BREAKING:** Complete the `trailhead` to `surface` public API cutover in core.
29
+
30
+ - `TraceRecord.trailhead` is now `TraceRecord.surface`.
31
+ - `SURFACE_KEY` now uses the `__trails_surface` extension key value, and the deprecated `TRAILHEAD_KEY` alias is removed.
32
+ - Deprecated `transport*` surface-error aliases are removed; import the existing `surface*` names instead.
33
+ - `isVisibleToTrailheads` is renamed to `isVisibleToSurfaces`.
34
+
35
+ See `docs/migration/trailhead-to-surface.md` for the full migration map.
36
+
37
+ - 112b9f2: Add `dryRun` to `TrailContext` and wire `--dry-run`. `TrailContext` gains an optional `dryRun?: boolean` field, defaulted to `false` in `createTrailContext`. `ExecuteTrailOptions` carries `dryRun?: boolean` through `applyContextOverrides` so `executeTrail(t, input, { dryRun: true })` produces `ctx.dryRun === true`. The CLI's existing `dryRunPreset` (auto-derived for `intent: 'write' | 'destroy'` trails) now flows through `META_FLAG_CANDIDATES` and reaches the executor via `runTrailOnce`, so `trails run booking.cancel … --dry-run` lands `ctx.dryRun === true` on the trail's blaze. Trails that don't read the field are unchanged. Read-intent trails don't get `--dry-run` exposed.
38
+ - 893025e: Add `--permit '<json>'` to inject an inline permit on `trails run`. New `permitPreset()` exposes a `--permit` string flag that the CLI build parses and validates against the `BasePermit` shape (`{ id: string, scopes: string[] }`) using a small Zod schema. Valid permits flow through `ExecuteTrailOptions.permit` → `applyContextOverrides` → `ctx.permit` so existing `enforcePermitRequirement` behavior just sees a populated permit. Invalid JSON or schema mismatch surface as `Result.err(ValidationError)` (exit code 1) before the trail runs, avoiding spurious `PermitError` results from malformed input. The flag is global, never routed into trail input (added to `META_FLAG_CANDIDATES`), and overlays only when defined.
39
+
40
+ Topographer now projects permit requirements into surface-map entries and classifies permit-tightening diffs as breaking when new scopes are required.
41
+
42
+ - eec5e9d: Default `ctx.logger` to a structured stdout console sink when `topo()` is called without an `observe:` option. Apps now get observability for free with zero configuration, per ADR-0041. Explicit `observe:` values (including `combine()` with no sinks, an explicit `Logger`, or an explicit `{ log }` config) are preserved untouched — the default is only injected when no `observe:` is supplied.
43
+ - ebd4434: Phase 7 starts: typed layers with optional object-shaped surface input. `Layer` gains an optional `input?: LayerInputSchema` field for surface projection (TRL-473/474 will project it onto CLI/MCP/HTTP). `executeTrail({ layers })` remains the canonical per-call wrapper option. Layers without `input` schemas stay surface-invisible and cover runtime-only concerns such as tenant guards, rate limiting, circuit breaking, and custom audit logging.
44
+ - 863d473: Add three attachment scopes for typed layers — trail, surface, topo — with composition order **topo → surface → trail → blaze**. `TrailSpec` and `Trail` gain `layers?: readonly Layer[]` (default `[]`). `topo()` accepts `{ layers: [...] }` as the third options argument; the topo carries those layers and they reach the executor via `ExecuteTrailOptions.topoLayers`. The CLI's `surface()`/`createProgram()`/`deriveCliCommands` already supports a `layers` option; that now flows through `runTrailOnce` as `surfaceLayers`. The executor builds the layer chain `[...topoLayers, ...surfaceLayers, ...trail.layers, ...options.layers]` so topo wraps surface wraps trail wraps blaze (verified by composition-order tests at every level). Survey's `TrailDetailReport` adds `composedLayers: { topo, surface, trail }` so agents can introspect the layer chain per trail. Backward-compatible: every new field is optional with a non-undefined default; existing call sites are unchanged.
45
+ - 344f2f7: Project typed-layer `input` schemas onto CLI flags. Each effective layer (topo + surface + trail composition order) with a non-undefined `input` schema gets its fields auto-derived into `--flag` options on every command it attaches to. Parsed values route to the layer at runtime via `ctx.extensions[LAYER_INPUTS_KEY][layer.name]` — `Layer.wrap` is unchanged. Collision rule: if a layer field name collides with a trail input field, another layer's projected name, or a CLI meta flag, the layer's flag is renamed to `--<layer-name>-<original-flag-name>` and a one-line warning emits to stderr (`[trails] ...`). Renames are deterministic across builds. New `LAYER_INPUTS_KEY` (exported from `@ontrails/core`) reserves the `ctx.extensions` slot.
46
+ - 26f9ffd: Project typed-layer `input` schemas onto MCP and HTTP surfaces. Closes Phase 7. Lifts `collectAttachedTypedLayers` and `projectLayerFieldName` (collision-rename rule) into `@ontrails/core/internal/layer-projection` so all three surfaces share one source of truth. The CLI surface refactors to consume the lifted helpers (no behavior change). MCP merges layer fields into each tool's `inputSchema` and partitions inbound args at invocation time. HTTP merges layer fields into the route's request schema (query for reads, body for writes) and exposes new optional `HttpRouteDefinition.inputSchema` + `layerInputProjections` for surface adapters / OpenAPI generators. Collision rule matches TRL-473's: deterministic rename to a layer-prefixed camelCase name with the original captured in the routing table. Side fix: MCP and HTTP handlers now forward `topoLayers: graph.layers` + `surfaceLayers: layers` so topo-scope layers actually compose at runtime (previously the handlers used the deprecated `layers` alias and never read `graph.layers`).
47
+ - 22c6c06: Accept ADR-0041 Unified Observability and ship the first activation and
48
+ observability primitives it depends on: activation trace records, topo-level
49
+ observe configuration, webhook activation materialization, signal/webhook
50
+ warden coaching, the `@ontrails/observe` package, sink composition, and
51
+ zero-dependency observe sinks.
52
+
53
+ ### Patch Changes
54
+
55
+ - 73622ae: Thread `ResourceSpec.config` through the built-in auth resource. Resource config schemas that accept `undefined` now receive their parsed default when config values are omitted, and `authResource` can materialize the no-op or JWT adapter from typed config while preserving existing mock and override paths.
56
+ - 6300f70: Refresh source comments and test labels for retired connector terminology as adapter guardrails become strict.
57
+ - d172013: Preserve specialized TrailsError identity and retry-exhaustion metadata when
58
+ serializing and deserializing framework errors.
59
+ - c3fc5c3: Move previously root-exported helper contracts out of `src/internal/*` to stable core module homes, document their public boundary, and guard the public barrel against future internal re-exports.
60
+ - 20d7a5c: Enforce the shared safe error projection policy for public error bodies, diagnostics, serialized payloads, and CLI stderr.
61
+ - be5fb46: Publish registry-driven error taxonomy documentation and checks from the core error registry.
62
+ - e898cc4: Add repo-level Knip dead-code detection and remove stale internal exports and unused package dependencies surfaced by the new check.
63
+ - 3395234: Move store adapter-binding helpers to `@ontrails/store/adapter-support` and topographer direct database/admin helpers to `@ontrails/topographer/backend-support`, keeping root exports focused on contract-level APIs.
64
+ - 4399fdb: Renamed `@ontrails/schema` to `@ontrails/topographer`. Mechanical rename only — no API changes. Update import sites from `@ontrails/schema` to `@ontrails/topographer`. See ADR-0042 for the durable graph substrate doctrine.
65
+
66
+ ## 1.0.0-beta.15
67
+
68
+ ### Minor Changes
69
+
70
+ - 4ad6b25: Lexicon rename cleanup (ADR-0023). Breaking for `@ontrails/core`, `@ontrails/cli`, and `@ontrails/tracing` at the boundary; internal-only churn for `@ontrails/warden`.
71
+
72
+ - **core**: the topo store schema renames `topo_provisions` / `topo_trail_provisions` → `topo_resources` / `topo_trail_resources` and `provision_count` → `resource_count`. Schema version bumped v4→v5. Stores still carrying the legacy schema are detected on open, dropped, and recreated from the new DDL — previous topo saves are cleared. Stored-data helpers `listTopoStoreProvisions` / `getTopoStoreProvision` / `readProvisionUsage` / `mapProvisionRow` renamed to their `resource` counterparts. TS row types `TopoTrailProvisionRow` / `TopoProvisionRow` renamed to `TopoTrailResourceRow` / `TopoResourceRow`.
73
+ - **cli**: CLI output mode env vars are now derived from the topo name per ADR-0023. Legacy globals `TRAILS_JSON` / `TRAILS_JSONL` are no longer honored — a topo named `stash` reads `STASH_JSON` / `STASH_JSONL`. `ActionResultContext` gains a `topoName: string` field; `resolveOutputMode(flags, topoName)` takes a topo name argument.
74
+ - **tracing**: legacy `.trails/dev/tracker.db` migration path removed. Any user still running a pre-rename beta build with a `tracker.db` should delete it or migrate before upgrading.
75
+ - **warden**: internal-only rename of `provisionDeclarations` / `provisionExists` rules and their trails to `resourceDeclarations` / `resourceExists`. No behavior change.
76
+
3
77
  ## 1.0.0-beta.14
4
78
 
5
79
  ### Minor Changes
package/README.md CHANGED
@@ -18,7 +18,7 @@ const greet = trail('greet', {
18
18
  blaze: (input) => Result.ok({ message: `Hello, ${input.name}!` }),
19
19
  });
20
20
 
21
- const app = topo('myapp', { greet });
21
+ const graph = topo('myapp', { greet });
22
22
  ```
23
23
 
24
24
  Trails compose other trails through `crosses` and `ctx.cross()`:
@@ -43,23 +43,26 @@ const onboard = trail('entity.onboard', {
43
43
  | --- | --- |
44
44
  | `trail(id, spec)` | Define a unit of work with typed input and `Result` output; use `crosses` for composition |
45
45
  | `signal(id, spec)` | Define a server-originated notification with a typed data schema |
46
- | `provision(id, spec)` | Define an infrastructure dependency with `create`, `dispose`, and optional `mock` |
47
- | `topo(name, ...modules)` | Collect trail modules into a queryable topology |
46
+ | `resource(id, spec)` | Define an infrastructure dependency with `create`, `dispose`, and optional `mock` |
47
+ | `drainResources(resources, ctx, configValues?)` | Evict and dispose cached resource singletons for surface/test shutdown |
48
+ | `blobRefSchema` / `createBlobRef(...)` | Declare and create binary output references with a shared descriptor contract |
49
+ | `topo(name, ...modules, options?)` | Collect trail modules into a queryable topology with optional `observe:` sinks |
50
+ | `deriveTrail(contour, operation, spec)` | Derive CRUD-shaped trail contracts from a contour on the `@ontrails/core/trails` subpath |
48
51
  | `validateTopo(topo)` | Structural validation: cross targets exist, no cycles, examples parse, output schemas present |
49
52
 
50
53
  ### Execution
51
54
 
52
55
  | Export | What it does |
53
56
  | --- | --- |
54
- | `executeTrail(trail, rawInput, options?)` | Centralized execution pipeline: validates input, builds context, composes gates, runs the implementation. Never throws -- exceptions become `Result.err(InternalError)`. |
57
+ | `executeTrail(trail, rawInput, options?)` | Centralized execution pipeline: validates input, builds context, composes layers, runs the implementation. Never throws -- exceptions become `Result.err(InternalError)`. |
55
58
  | `run(topo, id, input, options?)` | Headless trail execution by ID. Looks up the trail in the topo, then delegates to `executeTrail`. Returns `Result.err(NotFoundError)` if the ID is not registered. |
56
59
 
57
60
  ```typescript
58
- // executeTrail — trailheads use this directly
61
+ // executeTrail — surfaces use this directly
59
62
  const result = await executeTrail(greet, { name: 'Alice' });
60
63
 
61
- // run — no-trailhead execution by trail ID
62
- const result = await run(app, 'greet', { name: 'Alice' });
64
+ // run — headless execution by trail ID
65
+ const result = await run(graph, 'greet', { name: 'Alice' });
63
66
  if (result.isOk()) console.log(result.value);
64
67
  ```
65
68
 
@@ -89,7 +92,7 @@ Beyond the `trail(id, spec)` builder, `Topo` exposes these accessors:
89
92
 
90
93
  | Type | What it describes |
91
94
  | --- | --- |
92
- | `ExecuteTrailOptions` | Options for `executeTrail`: `ctx`, `abortSignal`, `gates`, `createContext` |
95
+ | `ExecuteTrailOptions` | Options for `executeTrail`: `ctx`, `abortSignal`, `layers`, `createContext` |
93
96
  | `RunOptions` | Same shape as `ExecuteTrailOptions`; forwarded by `run` |
94
97
 
95
98
  ### Result
@@ -112,38 +115,84 @@ result.unwrapOr(fallback); // Value or fallback
112
115
 
113
116
  ### Error taxonomy
114
117
 
115
- 13 error classes across 10 categories. Each maps deterministically to exit codes, HTTP status, and JSON-RPC codes on every trailhead.
118
+ The current taxonomy is generated from the `errorClasses` owner registry and
119
+ category code maps in `@ontrails/core`.
116
120
 
117
- | Category | Classes | HTTP | Retryable |
118
- | --- | --- | --- | --- |
119
- | `validation` | `ValidationError`, `AmbiguousError`, `AssertionError` | 400 | No |
120
- | `not_found` | `NotFoundError` | 404 | No |
121
- | `conflict` | `AlreadyExistsError`, `ConflictError` | 409 | No |
122
- | `permission` | `PermissionError` | 403 | No |
123
- | `timeout` | `TimeoutError` | 504 | Yes |
124
- | `rate_limit` | `RateLimitError` | 429 | Yes |
125
- | `network` | `NetworkError` | 502 | Yes |
126
- | `internal` | `InternalError` | 500 | No |
127
- | `auth` | `AuthError` | 401 | No |
128
- | `cancelled` | `CancelledError` | 499 | No |
121
+ <!-- error-taxonomy:start -->
122
+ <!-- GENERATED: run `bun run error-taxonomy:sync`; check with `bun run error-taxonomy:check`. Variant: category. -->
129
123
 
130
- The developer returns `Result.err(new NotFoundError(...))`. The framework maps it to the right code on every trailhead.
124
+ | Category | CLI Exit | HTTP | JSON-RPC | Retryable | Fixed Classes |
125
+ | --- | --- | --- | --- | --- | --- |
126
+ | `validation` | 1 | 400 | -32602 | No | `ValidationError`, `AmbiguousError` |
127
+ | `not_found` | 2 | 404 | -32601 | No | `NotFoundError` |
128
+ | `conflict` | 3 | 409 | -32603 | No | `AlreadyExistsError`, `ConflictError` |
129
+ | `permission` | 4 | 403 | -32600 | No | `PermissionError`, `PermitError` |
130
+ | `timeout` | 5 | 504 | -32603 | Yes | `TimeoutError` |
131
+ | `rate_limit` | 6 | 429 | -32603 | Yes | `RateLimitError` |
132
+ | `network` | 7 | 502 | -32603 | Yes | `NetworkError` |
133
+ | `internal` | 8 | 500 | -32603 | No | `AssertionError`, `InternalError`, `DerivationError`, `RecoverableCompletionError` |
134
+ | `auth` | 9 | 401 | -32600 | No | `AuthError` |
135
+ | `cancelled` | 130 | 499 | -32603 | No | `CancelledError` |
136
+
137
+ Dynamic classes:
138
+
139
+ - `RetryExhaustedError` inherits category and surface codes from its wrapped `TrailsError`; retryable is always No.
140
+ <!-- error-taxonomy:end -->
141
+
142
+ Public surface projections redact sensitive substrings before exposing a
143
+ non-internal `TrailsError` message. Internal-category `TrailsError` instances and
144
+ unknown native errors project with the generic message `Internal server error`;
145
+ diagnostics and serialized payloads keep their useful structure while redacting
146
+ messages, context, and stack strings.
147
+
148
+ The developer returns `Result.err(new NotFoundError(...))`. The framework maps it to the right code on every surface.
131
149
 
132
150
  ### Other exports
133
151
 
134
152
  - **Schema derivation** -- `deriveFields(schema)` extracts faithfully
135
153
  representable field metadata from Zod for prompts and forms
136
154
  - **Validation** -- `validateInput`, `formatZodIssues`, `zodToJsonSchema`
137
- - **Resilience** -- `retry`, `withTimeout`, `shouldRetry`, `getBackoffDelay`
155
+ - **Resilience** -- `retry`, `withTimeout`, `shouldRetry`, `deriveBackoffDelay`
138
156
  - **Serialization** -- `serializeError`, `deserializeError`
139
157
  - **Branded types** -- `uuid`, `email`, `nonEmptyString`, `positiveInt`
140
- - **Gates** -- cross-cutting gates via `composeGates`
158
+ - **Execution layers** -- low-level pipeline wrappers via `composeLayers`
141
159
  - **Guards and collections** -- `isDefined`, `chunk`, `dedupe`, `groupBy`, `sortBy`
142
160
  - **Patterns** (`@ontrails/core/patterns`) -- reusable Zod schemas for pagination, bulk ops, timestamps, sorting
161
+ - **Trail factories** (`@ontrails/core/trails`) -- derive CRUD-shaped trail contracts from contours without re-authoring IDs, schemas, examples, or intents
143
162
  - **Redaction** (`@ontrails/core/redaction`) -- strip sensitive data before logging
144
163
 
164
+ ### Public helper boundaries
165
+
166
+ The root package also exposes a few low-level contracts that other framework
167
+ packages build on:
168
+
169
+ - **Intrinsic tracing** -- `TraceRecord`, `TraceSink`, `TraceContext`, and the
170
+ sink registry helpers are the core-owned execution record shape shared by
171
+ `@ontrails/observe`, `@ontrails/tracing`, and adapters.
172
+ - **Trails DB** -- `deriveTrailsDbPath`, `deriveTrailsDir`,
173
+ `ensureSubsystemSchema`, `openReadTrailsDb`, and `openWriteTrailsDb` are the
174
+ generic database primitive used by framework subsystems.
175
+ - **Surface projection helpers** -- safe error projection, layer field
176
+ projection, cross-batch validation, late-bound signal references, and Zod
177
+ default-wrapper stripping are stable root exports for first-party surfaces,
178
+ store helpers, and tests.
179
+
145
180
  See the [API Reference](../../docs/api-reference.md) for the full list.
146
181
 
182
+ ## Migration: topo-store moved to `@ontrails/topographer`
183
+
184
+ Per [ADR-0042](../../docs/adr/0042-core-topographer-boundary-doctrine.md), the topo-store public API previously exported from `@ontrails/core` now lives in `@ontrails/topographer`. Generic `trails-db` helpers (`openReadTrailsDb`, `openWriteTrailsDb`, `ensureSubsystemSchema`, `deriveTrailsDbPath`, `deriveTrailsDir`) stay in core because tracing and other subsystems share them.
185
+
186
+ Update consumer imports:
187
+
188
+ ```diff
189
+ - import { topoStore, createTopoStore, createMockTopoStore, createTopoSnapshot, listTopoSnapshots, pinTopoSnapshot, unpinTopoSnapshot, createStoredTopoSnapshot, getStoredTopoExport, countTopoSnapshots, countPinnedSnapshots, countPrunableSnapshots, pruneUnpinnedSnapshots } from '@ontrails/core';
190
+ + import { topoStore, createTopoStore, createMockTopoStore, createTopoSnapshot, listTopoSnapshots, pinTopoSnapshot, unpinTopoSnapshot } from '@ontrails/topographer';
191
+ + import { createStoredTopoSnapshot, getStoredTopoExport, countTopoSnapshots, countPinnedSnapshots, countPrunableSnapshots, pruneUnpinnedSnapshots } from '@ontrails/topographer/backend-support';
192
+ ```
193
+
194
+ Types `ReadOnlyTopoStore`, `MockTopoStoreSeed`, `TopoSnapshot`, `TopoStoreRef`, `TopoStoreExportRecord`, `TopoStoreResourceRecord`, `TopoStoreTrailRecord`, `TopoStoreTrailDetailRecord`, `CreateTopoSnapshotInput`, and `ListTopoSnapshotsOptions` move to `@ontrails/topographer`. `StoredTopoExport` moves to `@ontrails/topographer/backend-support`.
195
+
147
196
  ## Installation
148
197
 
149
198
  ```bash
package/package.json CHANGED
@@ -1,14 +1,21 @@
1
1
  {
2
2
  "name": "@ontrails/core",
3
- "version": "1.0.0-beta.14",
3
+ "version": "1.0.0-beta.16",
4
+ "files": [
5
+ "src/**/*.ts",
6
+ "!src/**/__tests__/**",
7
+ "!src/**/*.test.ts",
8
+ "!src/**/*.test-d.ts",
9
+ "README.md",
10
+ "CHANGELOG.md"
11
+ ],
4
12
  "type": "module",
5
13
  "exports": {
6
14
  ".": "./src/index.ts",
7
- "./internal/topo-saves": "./src/internal/topo-saves.ts",
8
- "./internal/topo-store": "./src/internal/topo-store.ts",
9
- "./internal/trails-db": "./src/internal/trails-db.ts",
10
15
  "./patterns": "./src/patterns/index.ts",
11
16
  "./redaction": "./src/redaction/index.ts",
17
+ "./store": "./src/store/index.ts",
18
+ "./trails": "./src/trails/index.ts",
12
19
  "./package.json": "./package.json"
13
20
  },
14
21
  "scripts": {
@@ -0,0 +1,111 @@
1
+ import type {
2
+ ActivationSourceKind,
3
+ ActivationSourceMeta,
4
+ } from './activation-source.js';
5
+
6
+ export const ACTIVATION_PROVENANCE_KEY =
7
+ '__trails_activation_provenance' as const;
8
+
9
+ export interface ActivationProvenanceSource {
10
+ readonly cron?: string | undefined;
11
+ readonly id: string;
12
+ readonly kind: ActivationSourceKind;
13
+ readonly meta?: ActivationSourceMeta | undefined;
14
+ readonly producerTrailId?: string | undefined;
15
+ readonly timezone?: string | undefined;
16
+ }
17
+
18
+ export interface ActivationProvenance {
19
+ readonly fireId: string;
20
+ readonly parentFireId?: string | undefined;
21
+ readonly rootFireId: string;
22
+ readonly source: ActivationProvenanceSource;
23
+ }
24
+
25
+ export interface ActivationProvenanceCarrier {
26
+ readonly activation?: ActivationProvenance | undefined;
27
+ readonly extensions?: Readonly<Record<string, unknown>> | undefined;
28
+ }
29
+
30
+ const isObjectRecord = (value: unknown): value is Record<string, unknown> =>
31
+ typeof value === 'object' && value !== null && !Array.isArray(value);
32
+
33
+ const optionalString = (value: unknown): boolean =>
34
+ value === undefined || typeof value === 'string';
35
+
36
+ const isActivationProvenanceSource = (
37
+ value: unknown
38
+ ): value is ActivationProvenanceSource =>
39
+ isObjectRecord(value) &&
40
+ typeof value['id'] === 'string' &&
41
+ typeof value['kind'] === 'string' &&
42
+ optionalString(value['cron']) &&
43
+ optionalString(value['producerTrailId']) &&
44
+ optionalString(value['timezone']) &&
45
+ (value['meta'] === undefined || isObjectRecord(value['meta']));
46
+
47
+ const isActivationProvenance = (
48
+ value: unknown
49
+ ): value is ActivationProvenance =>
50
+ isObjectRecord(value) &&
51
+ typeof value['fireId'] === 'string' &&
52
+ optionalString(value['parentFireId']) &&
53
+ typeof value['rootFireId'] === 'string' &&
54
+ isActivationProvenanceSource(value['source']);
55
+
56
+ export const getActivationProvenance = (
57
+ ctx: ActivationProvenanceCarrier | undefined
58
+ ): ActivationProvenance | undefined => {
59
+ if (isActivationProvenance(ctx?.activation)) {
60
+ return ctx.activation;
61
+ }
62
+ const fromExtensions = ctx?.extensions?.[ACTIVATION_PROVENANCE_KEY];
63
+ return isActivationProvenance(fromExtensions) ? fromExtensions : undefined;
64
+ };
65
+
66
+ export const withActivationProvenance = <
67
+ TCtx extends {
68
+ readonly extensions?: Readonly<Record<string, unknown>> | undefined;
69
+ },
70
+ >(
71
+ ctx: TCtx,
72
+ activation: ActivationProvenance
73
+ ): TCtx & { readonly activation: ActivationProvenance } => ({
74
+ ...ctx,
75
+ activation,
76
+ extensions: {
77
+ ...ctx.extensions,
78
+ [ACTIVATION_PROVENANCE_KEY]: activation,
79
+ },
80
+ });
81
+
82
+ export const buildActivationProvenanceTraceAttrs = (
83
+ activation: ActivationProvenance | undefined
84
+ ): Readonly<Record<string, unknown>> => {
85
+ if (activation === undefined) {
86
+ return {};
87
+ }
88
+
89
+ const attrs: Record<string, unknown> = {
90
+ 'trails.activation.fire_id': activation.fireId,
91
+ 'trails.activation.root_fire_id': activation.rootFireId,
92
+ 'trails.activation.source.id': activation.source.id,
93
+ 'trails.activation.source.kind': activation.source.kind,
94
+ };
95
+
96
+ if (activation.parentFireId !== undefined) {
97
+ attrs['trails.activation.parent_fire_id'] = activation.parentFireId;
98
+ }
99
+ if (activation.source.producerTrailId !== undefined) {
100
+ attrs['trails.activation.source.producer_trail.id'] =
101
+ activation.source.producerTrailId;
102
+ }
103
+ if (activation.source.cron !== undefined) {
104
+ attrs['trails.activation.source.cron'] = activation.source.cron;
105
+ }
106
+ if (activation.source.timezone !== undefined) {
107
+ attrs['trails.activation.source.timezone'] = activation.source.timezone;
108
+ }
109
+
110
+ return attrs;
111
+ };