pipework 0.251.0 → 0.252.1

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 (730) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/core/config/load.d.ts +2 -0
  3. package/dist/core/config/load.d.ts.map +1 -1
  4. package/dist/core/config/load.js +1 -0
  5. package/dist/core/config/load.js.map +1 -1
  6. package/dist/core/config/namespace.d.ts +1 -0
  7. package/dist/core/config/namespace.d.ts.map +1 -1
  8. package/dist/core/config/schema.d.ts +2 -0
  9. package/dist/core/config/schema.d.ts.map +1 -1
  10. package/dist/core/config/schema.js +1 -0
  11. package/dist/core/config/schema.js.map +1 -1
  12. package/dist/core/surface/types.d.ts +1 -0
  13. package/dist/core/surface/types.d.ts.map +1 -1
  14. package/dist/data/db/namespace.d.ts +3 -0
  15. package/dist/data/db/namespace.d.ts.map +1 -1
  16. package/dist/data/db/namespace.js +3 -0
  17. package/dist/data/db/namespace.js.map +1 -1
  18. package/dist/data/db/pool.d.ts.map +1 -1
  19. package/dist/data/db/pool.js +6 -1
  20. package/dist/data/db/pool.js.map +1 -1
  21. package/dist/data/db/query-label.d.ts +5 -0
  22. package/dist/data/db/query-label.d.ts.map +1 -0
  23. package/dist/data/db/query-label.js +11 -0
  24. package/dist/data/db/query-label.js.map +1 -0
  25. package/dist/data/db/query-watch.d.ts +21 -0
  26. package/dist/data/db/query-watch.d.ts.map +1 -0
  27. package/dist/data/db/query-watch.js +90 -0
  28. package/dist/data/db/query-watch.js.map +1 -0
  29. package/dist/data/query/postgres-js/driver.js +1 -1
  30. package/dist/data/query/postgres-js/driver.js.map +1 -1
  31. package/dist/data/query/postgres-js/session.d.ts +5 -1
  32. package/dist/data/query/postgres-js/session.d.ts.map +1 -1
  33. package/dist/data/query/postgres-js/session.js +16 -11
  34. package/dist/data/query/postgres-js/session.js.map +1 -1
  35. package/dist/data/query/utils.d.ts +2 -0
  36. package/dist/data/query/utils.d.ts.map +1 -1
  37. package/dist/data/query/utils.js.map +1 -1
  38. package/dist/infra/credits/schema.d.ts +1 -1
  39. package/dist/test/plugin.d.ts.map +1 -1
  40. package/dist/test/plugin.js +10 -4
  41. package/dist/test/plugin.js.map +1 -1
  42. package/package.json +4 -3
  43. package/src/async/jobs/abortable-delay.ts +18 -0
  44. package/src/async/jobs/claims.ts +52 -0
  45. package/src/async/jobs/cron.ts +179 -0
  46. package/src/async/jobs/errors.ts +56 -0
  47. package/src/async/jobs/exclusion.ts +117 -0
  48. package/src/async/jobs/execute.ts +219 -0
  49. package/src/async/jobs/index.ts +10 -0
  50. package/src/async/jobs/listener.ts +135 -0
  51. package/src/async/jobs/namespace.ts +20 -0
  52. package/src/async/jobs/queue-door.ts +44 -0
  53. package/src/async/jobs/queue.ts +1012 -0
  54. package/src/async/jobs/run-script.ts +67 -0
  55. package/src/async/jobs/scheduler.ts +218 -0
  56. package/src/async/jobs/schedules-table.ts +37 -0
  57. package/src/async/jobs/serialize-error.ts +48 -0
  58. package/src/async/jobs/table.ts +191 -0
  59. package/src/async/pipeline/define.ts +53 -0
  60. package/src/async/pipeline/errors.ts +35 -0
  61. package/src/async/pipeline/execute.ts +53 -0
  62. package/src/async/pipeline/index.ts +13 -0
  63. package/src/async/pipeline/namespace.ts +12 -0
  64. package/src/async/pipeline/resume.ts +67 -0
  65. package/src/async/pipeline/run-steps.ts +98 -0
  66. package/src/async/pipeline/types.ts +57 -0
  67. package/src/async/state-machine/define.ts +64 -0
  68. package/src/async/state-machine/errors.ts +29 -0
  69. package/src/async/state-machine/index.ts +3 -0
  70. package/src/async/state-machine/namespace.ts +12 -0
  71. package/src/async/state-machine/transition.ts +90 -0
  72. package/src/async/state-machine/types.ts +37 -0
  73. package/src/async/steps/errors.ts +31 -0
  74. package/src/async/steps/graph.ts +1214 -0
  75. package/src/async/steps/hash.ts +40 -0
  76. package/src/async/steps/index.ts +7 -0
  77. package/src/async/steps/namespace.ts +7 -0
  78. package/src/async/steps/table.ts +97 -0
  79. package/src/async/steps/types.ts +318 -0
  80. package/src/audit/chain/index.ts +9 -0
  81. package/src/audit/chain/install.ts +113 -0
  82. package/src/audit/chain/retire.ts +52 -0
  83. package/src/audit/chain/verify.ts +257 -0
  84. package/src/audit/query/cursor.ts +37 -0
  85. package/src/audit/query/index.ts +9 -0
  86. package/src/audit/query/query.ts +223 -0
  87. package/src/audit/schema/audit-record-fields.ts +68 -0
  88. package/src/audit/schema/audit-record.ts +23 -0
  89. package/src/auth/auth/audit.ts +31 -0
  90. package/src/auth/auth/chain.ts +84 -0
  91. package/src/auth/auth/cookie.ts +136 -0
  92. package/src/auth/auth/email-links.ts +311 -0
  93. package/src/auth/auth/guard.ts +128 -0
  94. package/src/auth/auth/index.ts +18 -0
  95. package/src/auth/auth/multi-org.ts +337 -0
  96. package/src/auth/auth/namespace.ts +34 -0
  97. package/src/auth/auth/parse-expiry.ts +13 -0
  98. package/src/auth/auth/passwords.ts +110 -0
  99. package/src/auth/auth/schema.ts +110 -0
  100. package/src/auth/auth/sessions.ts +565 -0
  101. package/src/auth/auth/sign-in.ts +156 -0
  102. package/src/auth/auth/signing-keys.ts +69 -0
  103. package/src/auth/auth/types.ts +26 -0
  104. package/src/auth/auth/uuid.ts +10 -0
  105. package/src/auth/rbac/cache.ts +55 -0
  106. package/src/auth/rbac/check.ts +30 -0
  107. package/src/auth/rbac/create.ts +35 -0
  108. package/src/auth/rbac/index.ts +5 -0
  109. package/src/auth/rbac/middleware.ts +20 -0
  110. package/src/auth/rbac/namespace.ts +15 -0
  111. package/src/auth/rbac/resolve.ts +31 -0
  112. package/src/auth/rbac/schema.sql +31 -0
  113. package/src/auth/rbac/seed.ts +67 -0
  114. package/src/auth/rbac/tables.ts +32 -0
  115. package/src/auth/rbac/types.ts +65 -0
  116. package/src/auth/tenant/extract.ts +33 -0
  117. package/src/auth/tenant/in-tenant.ts +49 -0
  118. package/src/auth/tenant/index.ts +7 -0
  119. package/src/auth/tenant/namespace.ts +23 -0
  120. package/src/auth/tenant/propagate.ts +20 -0
  121. package/src/auth/tenant/rls.ts +120 -0
  122. package/src/auth/tenant/scope.ts +33 -0
  123. package/src/auth/tenant/scoped-db.ts +581 -0
  124. package/src/auth/tenant/types.ts +14 -0
  125. package/src/auth/tenant/validate.ts +27 -0
  126. package/src/cli/commands/add.ts +158 -0
  127. package/src/cli/commands/alerts.ts +98 -0
  128. package/src/cli/commands/check.ts +1418 -0
  129. package/src/cli/commands/codemod.ts +78 -0
  130. package/src/cli/commands/db.ts +356 -0
  131. package/src/cli/commands/dev.ts +101 -0
  132. package/src/cli/commands/generate.ts +75 -0
  133. package/src/cli/commands/init.ts +36 -0
  134. package/src/cli/commands/install.ts +28 -0
  135. package/src/cli/commands/lint.ts +62 -0
  136. package/src/cli/commands/migrate.ts +132 -0
  137. package/src/cli/commands/openapi.ts +63 -0
  138. package/src/cli/commands/remove.ts +72 -0
  139. package/src/cli/commands/run.ts +50 -0
  140. package/src/cli/commands/scope.ts +54 -0
  141. package/src/cli/commands/serve.ts +68 -0
  142. package/src/cli/commands/shard.ts +31 -0
  143. package/src/cli/commands/shared/config-pipework-version.ts +28 -0
  144. package/src/cli/commands/shared/find-config.ts +22 -0
  145. package/src/cli/commands/shared/load-config.ts +35 -0
  146. package/src/cli/commands/shared/pnpm-install.ts +95 -0
  147. package/src/cli/commands/shared/report-removed.ts +8 -0
  148. package/src/cli/commands/sync.ts +32 -0
  149. package/src/cli/commands/test.ts +307 -0
  150. package/src/cli/commands/upgrade.ts +48 -0
  151. package/src/cli/dev-bootstrap.ts +24 -0
  152. package/src/cli/errors.ts +10 -0
  153. package/src/cli/index.ts +303 -0
  154. package/src/cli/output.ts +17 -0
  155. package/src/cli/port.ts +15 -0
  156. package/src/cli/surface-kinds.ts +20 -0
  157. package/src/client/index.ts +4 -0
  158. package/src/client/poll.ts +130 -0
  159. package/src/client/report-fault.ts +119 -0
  160. package/src/core/config/app-pool.ts +19 -0
  161. package/src/core/config/aws-env.ts +29 -0
  162. package/src/core/config/base-dir.ts +24 -0
  163. package/src/core/config/discover.ts +64 -0
  164. package/src/core/config/env-resolve.ts +87 -0
  165. package/src/core/config/env-types.ts +116 -0
  166. package/src/core/config/env.ts +55 -0
  167. package/src/core/config/errors.ts +9 -0
  168. package/src/core/config/import-config.ts +40 -0
  169. package/src/core/config/index.ts +8 -0
  170. package/src/core/config/load.ts +417 -0
  171. package/src/core/config/namespace.ts +14 -0
  172. package/src/core/config/resolve.ts +195 -0
  173. package/src/core/config/schema.ts +488 -0
  174. package/src/core/config/statement-observer.ts +48 -0
  175. package/src/core/config/ts-inline-hooks.ts +75 -0
  176. package/src/core/config/ts-register.ts +4 -0
  177. package/src/core/config/ts-resolve-hooks.ts +101 -0
  178. package/src/core/errors/base.ts +49 -0
  179. package/src/core/errors/http.ts +146 -0
  180. package/src/core/errors/index.ts +2 -0
  181. package/src/core/errors/namespace.ts +31 -0
  182. package/src/core/lifecycle/drain.ts +33 -0
  183. package/src/core/lifecycle/health.ts +72 -0
  184. package/src/core/lifecycle/index.ts +4 -0
  185. package/src/core/lifecycle/namespace.ts +7 -0
  186. package/src/core/lifecycle/startup.ts +102 -0
  187. package/src/core/lifecycle/types.ts +36 -0
  188. package/src/core/logging/context.ts +60 -0
  189. package/src/core/logging/error-chain.ts +68 -0
  190. package/src/core/logging/index.ts +5 -0
  191. package/src/core/logging/logger.ts +65 -0
  192. package/src/core/logging/namespace.ts +16 -0
  193. package/src/core/logging/proxy.ts +22 -0
  194. package/src/core/logging/redact-match.ts +24 -0
  195. package/src/core/logging/types.ts +47 -0
  196. package/src/core/pipework.ts +566 -0
  197. package/src/core/runtime/broker.ts +69 -0
  198. package/src/core/surface/http.ts +133 -0
  199. package/src/core/surface/index.ts +11 -0
  200. package/src/core/surface/job-timeout.ts +40 -0
  201. package/src/core/surface/namespace.ts +13 -0
  202. package/src/core/surface/script.ts +33 -0
  203. package/src/core/surface/start.ts +142 -0
  204. package/src/core/surface/types.ts +225 -0
  205. package/src/core/surface/validate.ts +88 -0
  206. package/src/core/surface/worker.ts +528 -0
  207. package/src/core/validation/connectivity.ts +49 -0
  208. package/src/core/validation/domain.ts +99 -0
  209. package/src/core/validation/index.ts +5 -0
  210. package/src/core/validation/queue-tables.ts +312 -0
  211. package/src/core/validation/rls-role.ts +138 -0
  212. package/src/core/validation/startup.ts +51 -0
  213. package/src/core/validation/surfaces.ts +65 -0
  214. package/src/core/validation/types.ts +25 -0
  215. package/src/data/db/advisory-lock.ts +55 -0
  216. package/src/data/db/aggregates.ts +172 -0
  217. package/src/data/db/array-elements.ts +111 -0
  218. package/src/data/db/bulk-set.ts +53 -0
  219. package/src/data/db/col/index.ts +14 -0
  220. package/src/data/db/composed.ts +53 -0
  221. package/src/data/db/db.ts +276 -0
  222. package/src/data/db/excluded.ts +16 -0
  223. package/src/data/db/expressions.ts +473 -0
  224. package/src/data/db/filter.ts +90 -0
  225. package/src/data/db/function-source.ts +114 -0
  226. package/src/data/db/identifiers.ts +16 -0
  227. package/src/data/db/idx/index.ts +9 -0
  228. package/src/data/db/in-list.ts +49 -0
  229. package/src/data/db/index.ts +9 -0
  230. package/src/data/db/insert-split.ts +137 -0
  231. package/src/data/db/instrumentation.ts +82 -0
  232. package/src/data/db/maintenance.ts +28 -0
  233. package/src/data/db/namespace.ts +107 -0
  234. package/src/data/db/owner-labels.ts +9 -0
  235. package/src/data/db/pool.ts +187 -0
  236. package/src/data/db/query-label.ts +13 -0
  237. package/src/data/db/query-watch.ts +116 -0
  238. package/src/data/db/raw-client-warning.ts +37 -0
  239. package/src/data/db/readonly.ts +23 -0
  240. package/src/data/db/reservation.ts +151 -0
  241. package/src/data/db/schema-features.ts +14 -0
  242. package/src/data/db/serializable.ts +83 -0
  243. package/src/data/db/sql.ts +1 -0
  244. package/src/data/db/timeouts.ts +76 -0
  245. package/src/data/db/types.ts +18 -0
  246. package/src/data/db/unbound.ts +33 -0
  247. package/src/data/db/values.ts +29 -0
  248. package/src/data/domain/brand.ts +15 -0
  249. package/src/data/domain/build-factory.ts +193 -0
  250. package/src/data/domain/build-schema.ts +161 -0
  251. package/src/data/domain/build-table.ts +355 -0
  252. package/src/data/domain/define.ts +239 -0
  253. package/src/data/domain/external-registry.ts +34 -0
  254. package/src/data/domain/external.ts +77 -0
  255. package/src/data/domain/field.ts +279 -0
  256. package/src/data/domain/index.ts +13 -0
  257. package/src/data/domain/naming.ts +6 -0
  258. package/src/data/domain/projections.ts +57 -0
  259. package/src/data/domain/trace-safe-projection.ts +31 -0
  260. package/src/data/domain/traits.ts +108 -0
  261. package/src/data/domain/types.ts +289 -0
  262. package/src/data/jsonb/composed.ts +18 -0
  263. package/src/data/jsonb/index.ts +1 -0
  264. package/src/data/jsonb/namespace.ts +30 -0
  265. package/src/data/jsonb/query.ts +86 -0
  266. package/src/data/migrate/append-only-generate.ts +47 -0
  267. package/src/data/migrate/applied.ts +47 -0
  268. package/src/data/migrate/apply.ts +309 -0
  269. package/src/data/migrate/check.ts +119 -0
  270. package/src/data/migrate/diff.ts +357 -0
  271. package/src/data/migrate/door-generate.ts +130 -0
  272. package/src/data/migrate/framework-rls.ts +58 -0
  273. package/src/data/migrate/generate.ts +201 -0
  274. package/src/data/migrate/history.ts +215 -0
  275. package/src/data/migrate/index.ts +9 -0
  276. package/src/data/migrate/internal-definitions.ts +175 -0
  277. package/src/data/migrate/post-process.ts +73 -0
  278. package/src/data/migrate/pragma.ts +73 -0
  279. package/src/data/migrate/provision-framework.ts +147 -0
  280. package/src/data/migrate/rls-generate.ts +61 -0
  281. package/src/data/migrate/run.ts +124 -0
  282. package/src/data/migrate/safety.ts +167 -0
  283. package/src/data/migrate/snapshot.ts +368 -0
  284. package/src/data/migrate/sql-emit.ts +392 -0
  285. package/src/data/migrate/statements.ts +312 -0
  286. package/src/data/query/alias.ts +126 -0
  287. package/src/data/query/batch.ts +8 -0
  288. package/src/data/query/cache/core/cache.ts +78 -0
  289. package/src/data/query/cache/core/index.ts +1 -0
  290. package/src/data/query/cache/core/types.ts +29 -0
  291. package/src/data/query/cache/readme.md +230 -0
  292. package/src/data/query/casing.ts +76 -0
  293. package/src/data/query/collation.ts +11 -0
  294. package/src/data/query/column-builder.ts +370 -0
  295. package/src/data/query/column.ts +150 -0
  296. package/src/data/query/entity.ts +42 -0
  297. package/src/data/query/errors.ts +33 -0
  298. package/src/data/query/index.ts +14 -0
  299. package/src/data/query/logger.ts +47 -0
  300. package/src/data/query/operations.ts +45 -0
  301. package/src/data/query/pg-core/alias.ts +12 -0
  302. package/src/data/query/pg-core/checks.ts +32 -0
  303. package/src/data/query/pg-core/columns/all.ts +71 -0
  304. package/src/data/query/pg-core/columns/bigint.ts +110 -0
  305. package/src/data/query/pg-core/columns/bigserial.ts +128 -0
  306. package/src/data/query/pg-core/columns/boolean.ts +43 -0
  307. package/src/data/query/pg-core/columns/char.ts +85 -0
  308. package/src/data/query/pg-core/columns/cidr.ts +43 -0
  309. package/src/data/query/pg-core/columns/common.ts +366 -0
  310. package/src/data/query/pg-core/columns/custom.ts +232 -0
  311. package/src/data/query/pg-core/columns/date.common.ts +15 -0
  312. package/src/data/query/pg-core/columns/date.ts +112 -0
  313. package/src/data/query/pg-core/columns/double-precision.ts +55 -0
  314. package/src/data/query/pg-core/columns/enum.ts +201 -0
  315. package/src/data/query/pg-core/columns/index.ts +35 -0
  316. package/src/data/query/pg-core/columns/inet.ts +43 -0
  317. package/src/data/query/pg-core/columns/int.common.ts +57 -0
  318. package/src/data/query/pg-core/columns/integer.ts +53 -0
  319. package/src/data/query/pg-core/columns/interval.ts +83 -0
  320. package/src/data/query/pg-core/columns/json.ts +58 -0
  321. package/src/data/query/pg-core/columns/jsonb.ts +56 -0
  322. package/src/data/query/pg-core/columns/line.ts +117 -0
  323. package/src/data/query/pg-core/columns/macaddr.ts +43 -0
  324. package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
  325. package/src/data/query/pg-core/columns/numeric.ts +227 -0
  326. package/src/data/query/pg-core/columns/point.ts +127 -0
  327. package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
  328. package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
  329. package/src/data/query/pg-core/columns/real.ts +58 -0
  330. package/src/data/query/pg-core/columns/serial.ts +55 -0
  331. package/src/data/query/pg-core/columns/smallint.ts +53 -0
  332. package/src/data/query/pg-core/columns/smallserial.ts +60 -0
  333. package/src/data/query/pg-core/columns/text.ts +67 -0
  334. package/src/data/query/pg-core/columns/time.ts +72 -0
  335. package/src/data/query/pg-core/columns/timestamp.ts +163 -0
  336. package/src/data/query/pg-core/columns/uuid.ts +51 -0
  337. package/src/data/query/pg-core/columns/varchar.ts +89 -0
  338. package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
  339. package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
  340. package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
  341. package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
  342. package/src/data/query/pg-core/db.ts +674 -0
  343. package/src/data/query/pg-core/dialect.ts +1404 -0
  344. package/src/data/query/pg-core/expressions.ts +25 -0
  345. package/src/data/query/pg-core/foreign-keys.ts +130 -0
  346. package/src/data/query/pg-core/index.ts +21 -0
  347. package/src/data/query/pg-core/indexes.ts +276 -0
  348. package/src/data/query/pg-core/policies.ts +56 -0
  349. package/src/data/query/pg-core/primary-keys.ts +62 -0
  350. package/src/data/query/pg-core/query-builders/count.ts +86 -0
  351. package/src/data/query/pg-core/query-builders/delete.ts +293 -0
  352. package/src/data/query/pg-core/query-builders/index.ts +7 -0
  353. package/src/data/query/pg-core/query-builders/insert.ts +452 -0
  354. package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
  355. package/src/data/query/pg-core/query-builders/query.ts +157 -0
  356. package/src/data/query/pg-core/query-builders/raw.ts +49 -0
  357. package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
  358. package/src/data/query/pg-core/query-builders/select.ts +1346 -0
  359. package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
  360. package/src/data/query/pg-core/query-builders/update.ts +626 -0
  361. package/src/data/query/pg-core/roles.ts +41 -0
  362. package/src/data/query/pg-core/schema.ts +72 -0
  363. package/src/data/query/pg-core/sequence.ts +41 -0
  364. package/src/data/query/pg-core/session.ts +292 -0
  365. package/src/data/query/pg-core/subquery.ts +46 -0
  366. package/src/data/query/pg-core/table.ts +252 -0
  367. package/src/data/query/pg-core/unique-constraint.ts +73 -0
  368. package/src/data/query/pg-core/utils/array.ts +95 -0
  369. package/src/data/query/pg-core/utils/index.ts +1 -0
  370. package/src/data/query/pg-core/utils.ts +104 -0
  371. package/src/data/query/pg-core/view-base.ts +14 -0
  372. package/src/data/query/pg-core/view-common.ts +1 -0
  373. package/src/data/query/pg-core/view.ts +435 -0
  374. package/src/data/query/pg-core/with-builder.ts +41 -0
  375. package/src/data/query/postgres-js/README.md +46 -0
  376. package/src/data/query/postgres-js/array-parser.ts +45 -0
  377. package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
  378. package/src/data/query/postgres-js/driver.ts +163 -0
  379. package/src/data/query/postgres-js/index.ts +2 -0
  380. package/src/data/query/postgres-js/session.ts +234 -0
  381. package/src/data/query/primary-key.ts +11 -0
  382. package/src/data/query/query-builders/query-builder.ts +19 -0
  383. package/src/data/query/query-builders/select.types.ts +175 -0
  384. package/src/data/query/query-promise.ts +35 -0
  385. package/src/data/query/relations.ts +725 -0
  386. package/src/data/query/runnable-query.ts +12 -0
  387. package/src/data/query/selection-proxy.ts +121 -0
  388. package/src/data/query/session.ts +8 -0
  389. package/src/data/query/sql/expressions/conditions.ts +741 -0
  390. package/src/data/query/sql/expressions/index.ts +2 -0
  391. package/src/data/query/sql/expressions/select.ts +45 -0
  392. package/src/data/query/sql/functions/aggregate.ts +129 -0
  393. package/src/data/query/sql/functions/index.ts +2 -0
  394. package/src/data/query/sql/functions/vector.ts +178 -0
  395. package/src/data/query/sql/index.ts +3 -0
  396. package/src/data/query/sql/sql.ts +794 -0
  397. package/src/data/query/subquery.ts +53 -0
  398. package/src/data/query/table.ts +208 -0
  399. package/src/data/query/table.utils.ts +2 -0
  400. package/src/data/query/tracing-utils.ts +3 -0
  401. package/src/data/query/tracing.ts +11 -0
  402. package/src/data/query/utils.ts +357 -0
  403. package/src/data/query/version.ts +4 -0
  404. package/src/data/query/view-common.ts +1 -0
  405. package/src/data/schema/branded.ts +13 -0
  406. package/src/data/schema/generated/coerce.ts +5 -0
  407. package/src/data/schema/generated/combinator.ts +6 -0
  408. package/src/data/schema/generated/encoding.ts +5 -0
  409. package/src/data/schema/generated/error.ts +6 -0
  410. package/src/data/schema/generated/format.ts +5 -0
  411. package/src/data/schema/generated/type-constructor.ts +10 -0
  412. package/src/data/schema/generated/type.ts +6 -0
  413. package/src/data/schema/index.ts +6 -0
  414. package/src/data/schema/json-schema.ts +33 -0
  415. package/src/data/schema/namespace.ts +55 -0
  416. package/src/data/schema/parse.ts +39 -0
  417. package/src/data/schema/types.ts +39 -0
  418. package/src/data/temporal/append-only.ts +134 -0
  419. package/src/data/temporal/close.ts +27 -0
  420. package/src/data/temporal/columns.ts +10 -0
  421. package/src/data/temporal/definition-queries.ts +70 -0
  422. package/src/data/temporal/errors.ts +10 -0
  423. package/src/data/temporal/get-current.ts +22 -0
  424. package/src/data/temporal/index.ts +9 -0
  425. package/src/data/temporal/namespace.ts +36 -0
  426. package/src/data/temporal/query.ts +25 -0
  427. package/src/data/temporal/resolve.ts +17 -0
  428. package/src/data/temporal/revise.ts +67 -0
  429. package/src/data/temporal/types.ts +22 -0
  430. package/src/data/valve/artifact.ts +33 -0
  431. package/src/data/valve/contract-diff.ts +21 -0
  432. package/src/data/valve/cross.ts +57 -0
  433. package/src/data/valve/crossing-ledger.ts +50 -0
  434. package/src/data/valve/decision.ts +44 -0
  435. package/src/data/valve/durable-crossing.ts +52 -0
  436. package/src/data/valve/execute-crossing.ts +77 -0
  437. package/src/data/valve/faucet.ts +56 -0
  438. package/src/data/valve/gate.ts +114 -0
  439. package/src/data/valve/graph.ts +77 -0
  440. package/src/data/valve/index.ts +53 -0
  441. package/src/data/valve/namespace.ts +57 -0
  442. package/src/data/valve/registry.ts +50 -0
  443. package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
  444. package/src/data/valve/schema/valve-crossing.ts +9 -0
  445. package/src/data/valve/supply.ts +154 -0
  446. package/src/data/valve/types.ts +143 -0
  447. package/src/data/vector/columns.ts +27 -0
  448. package/src/data/vector/index.ts +4 -0
  449. package/src/data/vector/namespace.ts +33 -0
  450. package/src/data/vector/query.ts +85 -0
  451. package/src/data/vector/validate.ts +16 -0
  452. package/src/data/write/audit/actor.ts +15 -0
  453. package/src/data/write/audit/audit-columns.ts +18 -0
  454. package/src/data/write/audit/audit-select.ts +111 -0
  455. package/src/data/write/audit/bound-transaction.ts +14 -0
  456. package/src/data/write/audit/cte-compile.ts +32 -0
  457. package/src/data/write/audit/decode-returning.ts +47 -0
  458. package/src/data/write/audit/final-select.ts +43 -0
  459. package/src/data/write/audit/infra-audit.ts +36 -0
  460. package/src/data/write/audit/primary-key.ts +65 -0
  461. package/src/data/write/audit/projection.ts +41 -0
  462. package/src/data/write/audit/read-touches.ts +86 -0
  463. package/src/data/write/audit/touch-match.ts +78 -0
  464. package/src/data/write/audit/verb-delete.ts +62 -0
  465. package/src/data/write/audit/verb-insert.ts +36 -0
  466. package/src/data/write/audit/verb-select.ts +47 -0
  467. package/src/data/write/audit/verb-update.ts +60 -0
  468. package/src/data/write/audit/verb-upsert.ts +104 -0
  469. package/src/data/write/conflict.ts +43 -0
  470. package/src/data/write/delete.ts +38 -0
  471. package/src/data/write/execute.ts +243 -0
  472. package/src/data/write/index.ts +11 -0
  473. package/src/data/write/insert.ts +63 -0
  474. package/src/data/write/state.ts +43 -0
  475. package/src/data/write/update.ts +54 -0
  476. package/src/data/write/upsert.ts +58 -0
  477. package/src/data/write/values.ts +19 -0
  478. package/src/index.ts +230 -0
  479. package/src/infra/access-links/code.ts +70 -0
  480. package/src/infra/access-links/handle.ts +892 -0
  481. package/src/infra/access-links/index.ts +9 -0
  482. package/src/infra/access-links/namespace.ts +30 -0
  483. package/src/infra/access-links/person-check.ts +177 -0
  484. package/src/infra/access-links/schema.ts +71 -0
  485. package/src/infra/alerts/async-sources.ts +231 -0
  486. package/src/infra/alerts/audit.ts +36 -0
  487. package/src/infra/alerts/beat.ts +123 -0
  488. package/src/infra/alerts/client-faults.ts +111 -0
  489. package/src/infra/alerts/faults.ts +156 -0
  490. package/src/infra/alerts/handle.ts +778 -0
  491. package/src/infra/alerts/http.ts +192 -0
  492. package/src/infra/alerts/index.ts +12 -0
  493. package/src/infra/alerts/infra-sources.ts +180 -0
  494. package/src/infra/alerts/namespace.ts +81 -0
  495. package/src/infra/alerts/redact.ts +21 -0
  496. package/src/infra/alerts/request-faults.ts +41 -0
  497. package/src/infra/alerts/schema.ts +124 -0
  498. package/src/infra/alerts/sinks.ts +125 -0
  499. package/src/infra/alerts/source-options.ts +26 -0
  500. package/src/infra/alerts/sources.ts +503 -0
  501. package/src/infra/alerts/subsystem-sources.ts +137 -0
  502. package/src/infra/audit/emit.ts +87 -0
  503. package/src/infra/audit/index.ts +2 -0
  504. package/src/infra/audit/namespace.ts +22 -0
  505. package/src/infra/audit/schema.sql +35 -0
  506. package/src/infra/audit/types.ts +18 -0
  507. package/src/infra/aws/credentials.ts +147 -0
  508. package/src/infra/aws/sigv4.ts +140 -0
  509. package/src/infra/cache/create.ts +58 -0
  510. package/src/infra/cache/entry.ts +81 -0
  511. package/src/infra/cache/index.ts +4 -0
  512. package/src/infra/cache/namespace.ts +10 -0
  513. package/src/infra/cache/tenant.ts +93 -0
  514. package/src/infra/cache/types.ts +24 -0
  515. package/src/infra/crawl/audit.ts +35 -0
  516. package/src/infra/crawl/errors.ts +25 -0
  517. package/src/infra/crawl/handle.ts +693 -0
  518. package/src/infra/crawl/index.ts +9 -0
  519. package/src/infra/crawl/links.ts +160 -0
  520. package/src/infra/crawl/namespace.ts +36 -0
  521. package/src/infra/crawl/robots.ts +100 -0
  522. package/src/infra/crawl/schema.ts +89 -0
  523. package/src/infra/credit-line/handle.ts +883 -0
  524. package/src/infra/credit-line/index.ts +6 -0
  525. package/src/infra/credit-line/namespace.ts +7 -0
  526. package/src/infra/credit-line/schema.ts +96 -0
  527. package/src/infra/credits/handle.ts +706 -0
  528. package/src/infra/credits/index.ts +5 -0
  529. package/src/infra/credits/namespace.ts +7 -0
  530. package/src/infra/credits/schema.ts +83 -0
  531. package/src/infra/email/audit.ts +36 -0
  532. package/src/infra/email/inbound.ts +622 -0
  533. package/src/infra/email/index.ts +11 -0
  534. package/src/infra/email/mail.ts +517 -0
  535. package/src/infra/email/mime.ts +447 -0
  536. package/src/infra/email/namespace.ts +22 -0
  537. package/src/infra/email/providers.ts +111 -0
  538. package/src/infra/email/schema.ts +96 -0
  539. package/src/infra/email/sns.ts +200 -0
  540. package/src/infra/email/unsubscribe.ts +44 -0
  541. package/src/infra/fetch/address.ts +88 -0
  542. package/src/infra/fetch/connect-retry.ts +87 -0
  543. package/src/infra/fetch/handle.ts +329 -0
  544. package/src/infra/fetch/index.ts +7 -0
  545. package/src/infra/fetch/namespace.ts +70 -0
  546. package/src/infra/idempotency/index.ts +3 -0
  547. package/src/infra/idempotency/middleware.ts +87 -0
  548. package/src/infra/idempotency/store.ts +92 -0
  549. package/src/infra/idempotency/types.ts +30 -0
  550. package/src/infra/join-requests/handle.ts +312 -0
  551. package/src/infra/join-requests/index.ts +2 -0
  552. package/src/infra/join-requests/namespace.ts +7 -0
  553. package/src/infra/join-requests/schema.ts +33 -0
  554. package/src/infra/outbox/core.ts +165 -0
  555. package/src/infra/quota/errors.ts +32 -0
  556. package/src/infra/quota/handle.ts +215 -0
  557. package/src/infra/quota/index.ts +5 -0
  558. package/src/infra/quota/namespace.ts +7 -0
  559. package/src/infra/quota/schema.ts +15 -0
  560. package/src/infra/storage/backend.ts +34 -0
  561. package/src/infra/storage/handle.ts +513 -0
  562. package/src/infra/storage/index.ts +9 -0
  563. package/src/infra/storage/local.ts +104 -0
  564. package/src/infra/storage/namespace.ts +13 -0
  565. package/src/infra/storage/s3.ts +257 -0
  566. package/src/infra/storage/schema.ts +24 -0
  567. package/src/infra/support/handle.ts +854 -0
  568. package/src/infra/support/http.ts +229 -0
  569. package/src/infra/support/index.ts +7 -0
  570. package/src/infra/support/namespace.ts +12 -0
  571. package/src/infra/support/schema.ts +96 -0
  572. package/src/infra/webhook/inbound.ts +45 -0
  573. package/src/infra/webhook/index.ts +5 -0
  574. package/src/infra/webhook/namespace.ts +24 -0
  575. package/src/infra/webhook/outbound.ts +315 -0
  576. package/src/infra/webhook/sign.ts +32 -0
  577. package/src/infra/webhook/verify.ts +82 -0
  578. package/src/invariants/assert.ts +26 -0
  579. package/src/invariants/index.ts +1 -0
  580. package/src/lint/config.ts +56 -0
  581. package/src/lint/doctrine.ts +163 -0
  582. package/src/lint/include.ts +97 -0
  583. package/src/lint/index.ts +3 -0
  584. package/src/lint/preset.ts +10 -0
  585. package/src/lint/resolver.ts +218 -0
  586. package/src/lint/rules/no-reexports.ts +46 -0
  587. package/src/request/behavior/audited.ts +85 -0
  588. package/src/request/behavior/cached.ts +62 -0
  589. package/src/request/behavior/compose.ts +28 -0
  590. package/src/request/behavior/index.ts +5 -0
  591. package/src/request/behavior/namespace.ts +16 -0
  592. package/src/request/behavior/types.ts +26 -0
  593. package/src/request/behavior/versioned.ts +54 -0
  594. package/src/request/context/create.ts +103 -0
  595. package/src/request/context/guard.ts +49 -0
  596. package/src/request/context/index.ts +4 -0
  597. package/src/request/context/run-in-transaction.ts +200 -0
  598. package/src/request/context/store.ts +28 -0
  599. package/src/request/context/types.ts +50 -0
  600. package/src/request/di/builder.ts +535 -0
  601. package/src/request/di/index.ts +8 -0
  602. package/src/request/di/resolve.ts +271 -0
  603. package/src/request/di/types.ts +262 -0
  604. package/src/request/fitting/namespace.ts +7 -0
  605. package/src/request/fixture/batch.ts +71 -0
  606. package/src/request/fixture/builder.ts +26 -0
  607. package/src/request/fixture/errors.ts +10 -0
  608. package/src/request/fixture/index.ts +8 -0
  609. package/src/request/fixture/namespace.ts +23 -0
  610. package/src/request/fixture/paginate.ts +44 -0
  611. package/src/request/fixture/to-handlers.ts +260 -0
  612. package/src/request/fixture/types.ts +79 -0
  613. package/src/request/flow/act-as.ts +78 -0
  614. package/src/request/flow/namespace.ts +17 -0
  615. package/src/request/http/error-step.ts +42 -0
  616. package/src/request/http/file.ts +141 -0
  617. package/src/request/http/index.ts +4 -0
  618. package/src/request/http/middleware.ts +141 -0
  619. package/src/request/http/namespace.ts +5 -0
  620. package/src/request/http/rate-limit-classes.ts +170 -0
  621. package/src/request/http/response.ts +82 -0
  622. package/src/request/http/server.ts +916 -0
  623. package/src/request/http/sniff.ts +261 -0
  624. package/src/request/http/types.ts +250 -0
  625. package/src/request/http/upload.ts +284 -0
  626. package/src/request/internal/text.ts +6 -0
  627. package/src/request/openapi/generate.ts +205 -0
  628. package/src/request/openapi/index.ts +2 -0
  629. package/src/request/openapi/namespace.ts +7 -0
  630. package/src/test/auth.ts +13 -0
  631. package/src/test/auto-setup.ts +45 -0
  632. package/src/test/context.ts +91 -0
  633. package/src/test/crawl-fixture.ts +157 -0
  634. package/src/test/discover-fork.ts +17 -0
  635. package/src/test/fingerprint.ts +135 -0
  636. package/src/test/globals.d.ts +7 -0
  637. package/src/test/index.ts +19 -0
  638. package/src/test/namespace.ts +87 -0
  639. package/src/test/plugin.ts +189 -0
  640. package/src/test/progress.ts +185 -0
  641. package/src/test/reap-after-run.ts +28 -0
  642. package/src/test/reap.ts +286 -0
  643. package/src/test/reset.ts +253 -0
  644. package/src/test/savepoints.ts +172 -0
  645. package/src/test/setup.ts +1422 -0
  646. package/src/test/system-channel.ts +50 -0
  647. package/src/test/vitest-plugin.ts +142 -0
  648. package/src/test/vitest-workspace.ts +507 -0
  649. package/src/test/vitest.ts +333 -0
  650. package/src/test/watch.ts +105 -0
  651. package/src/trace/capture/bounded-serializer.ts +146 -0
  652. package/src/trace/cardinality/analyze.ts +173 -0
  653. package/src/trace/cardinality/branch-context.ts +214 -0
  654. package/src/trace/cardinality/check.ts +33 -0
  655. package/src/trace/cardinality/classify-edge.ts +64 -0
  656. package/src/trace/cardinality/structural-max.ts +107 -0
  657. package/src/trace/check/coverage-check.ts +188 -0
  658. package/src/trace/check/flow-check.ts +103 -0
  659. package/src/trace/check/flow-step-site.ts +234 -0
  660. package/src/trace/check/io-pattern.ts +116 -0
  661. package/src/trace/codemod/add-cardinality.ts +152 -0
  662. package/src/trace/codemod/run.ts +80 -0
  663. package/src/trace/entry/child-trace.ts +21 -0
  664. package/src/trace/entry/close-trace.ts +87 -0
  665. package/src/trace/entry/finalize-trace.ts +28 -0
  666. package/src/trace/entry/open-trace.ts +138 -0
  667. package/src/trace/entry/parent-trace.ts +20 -0
  668. package/src/trace/entry/parse-traceparent.ts +39 -0
  669. package/src/trace/entry/process-start.ts +38 -0
  670. package/src/trace/entry/trace-context.ts +26 -0
  671. package/src/trace/entry/tracing-enabled.ts +10 -0
  672. package/src/trace/external/record.ts +195 -0
  673. package/src/trace/external/report.ts +66 -0
  674. package/src/trace/namespace.ts +19 -0
  675. package/src/trace/partition/day.ts +47 -0
  676. package/src/trace/partition/index.ts +14 -0
  677. package/src/trace/partition/partition-name.ts +23 -0
  678. package/src/trace/partition/plan.ts +82 -0
  679. package/src/trace/partition/schedule.ts +26 -0
  680. package/src/trace/partition/startup-hook.ts +39 -0
  681. package/src/trace/partition/sync.ts +154 -0
  682. package/src/trace/partition/tables.ts +53 -0
  683. package/src/trace/read/tree.ts +83 -0
  684. package/src/trace/retain/copy-on-error.ts +76 -0
  685. package/src/trace/runtime/expire-stale-traces.ts +54 -0
  686. package/src/trace/runtime/flow-step.ts +147 -0
  687. package/src/trace/runtime/flush-steps.ts +31 -0
  688. package/src/trace/runtime/pending-writes.ts +54 -0
  689. package/src/trace/runtime/step-buffer.ts +298 -0
  690. package/src/trace/runtime/step-error.ts +21 -0
  691. package/src/trace/runtime/step-meta.ts +55 -0
  692. package/src/trace/runtime/thenable.ts +12 -0
  693. package/src/trace/runtime/truncate-trace.ts +62 -0
  694. package/src/trace/schema/trace-fields.ts +52 -0
  695. package/src/trace/schema/trace-retained.ts +22 -0
  696. package/src/trace/schema/trace-step-fields.ts +44 -0
  697. package/src/trace/schema/trace-step-retained.ts +25 -0
  698. package/src/trace/schema/trace-step.ts +18 -0
  699. package/src/trace/schema/trace.ts +12 -0
  700. package/src/trace/transformer/apply.ts +79 -0
  701. package/src/trace/transformer/build-meta-literal.ts +30 -0
  702. package/src/trace/transformer/find-flow-step-sites.ts +85 -0
  703. package/src/trace/transformer/inject-flow-step-import.ts +39 -0
  704. package/src/trace/transformer/transform-error.ts +14 -0
  705. package/src/trace/transformer/transform-flow-steps.ts +123 -0
  706. package/src/trace/transformer/wrap-function-declaration.ts +62 -0
  707. package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
  708. package/src/workspace/affected.ts +110 -0
  709. package/src/workspace/changed-files.ts +163 -0
  710. package/src/workspace/check-deps.ts +213 -0
  711. package/src/workspace/checksum.ts +20 -0
  712. package/src/workspace/dependency-graph.ts +67 -0
  713. package/src/workspace/detect-pipework-copies.ts +93 -0
  714. package/src/workspace/discover.ts +206 -0
  715. package/src/workspace/generate.ts +401 -0
  716. package/src/workspace/index.ts +7 -0
  717. package/src/workspace/module-imports-pipework.ts +39 -0
  718. package/src/workspace/module-package-name.ts +12 -0
  719. package/src/workspace/scrub-git-env.ts +23 -0
  720. package/src/workspace/source-paths.ts +36 -0
  721. package/src/workspace/sync.ts +182 -0
  722. package/dist/REFERENCE.md +0 -1477
  723. package/dist/infra/access-links/rate-limit.d.ts +0 -10
  724. package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
  725. package/dist/infra/access-links/rate-limit.js +0 -28
  726. package/dist/infra/access-links/rate-limit.js.map +0 -1
  727. package/dist/infra/email/sigv4.d.ts +0 -24
  728. package/dist/infra/email/sigv4.d.ts.map +0 -1
  729. package/dist/infra/email/sigv4.js +0 -55
  730. package/dist/infra/email/sigv4.js.map +0 -1
@@ -0,0 +1,53 @@
1
+ // The partitioned tables the substrate manages, plus the retention window each
2
+ // one obeys. Three retention classes share one partition lifecycle:
3
+ //
4
+ // - **hot** (`trace`, `trace_step`) — `hotRetentionDays`, short-lived.
5
+ // - **cold** (`trace_retained`, `trace_step_retained`) — `errorRetentionDays`,
6
+ // copy-on-error survives past hot retention.
7
+ // - **audit** (`audit_record`) — `auditRetentionDays`, long / indefinite; the
8
+ // audit projection lives independently of trace storage.
9
+ //
10
+ // Partition creation uses the same `partitionLeadDays` for all three classes —
11
+ // inserts on any class must never race partition creation.
12
+
13
+ import { trace } from '../schema/trace.js'
14
+ import { traceStep } from '../schema/trace-step.js'
15
+ import { traceRetained } from '../schema/trace-retained.js'
16
+ import { traceStepRetained } from '../schema/trace-step-retained.js'
17
+ import { auditRecord } from '../../audit/schema/audit-record.js'
18
+
19
+ export type RetentionClass = 'hot' | 'cold' | 'audit'
20
+
21
+ export interface PartitionedTraceTable {
22
+ /** The parent table's wire name — partitions are children of this. */
23
+ readonly parent: string
24
+ readonly retention: RetentionClass
25
+ }
26
+
27
+ export const PARTITIONED_TRACE_TABLES: readonly PartitionedTraceTable[] = [
28
+ { parent: trace.$name, retention: 'hot' },
29
+ { parent: traceStep.$name, retention: 'hot' },
30
+ { parent: traceRetained.$name, retention: 'cold' },
31
+ { parent: traceStepRetained.$name, retention: 'cold' },
32
+ { parent: auditRecord.$name, retention: 'audit' },
33
+ ]
34
+
35
+ /**
36
+ * Wire names of the framework-owned partitioned tables. A `pipework generate`
37
+ * must not emit these into an application migration (a bare `CREATE TABLE` of a
38
+ * `PARTITION BY RANGE` table accepts no inserts), and the test harness
39
+ * provisions them — parent plus day partitions — itself. Issue #313.
40
+ */
41
+ export const PARTITIONED_TRACE_TABLE_NAMES: ReadonlySet<string> = new Set(
42
+ PARTITIONED_TRACE_TABLES.map(t => t.parent),
43
+ )
44
+
45
+ /**
46
+ * Each step table with the trace table its foreign key points at. A day's step
47
+ * partition must go before the trace partition it references, so retention
48
+ * drops the two together.
49
+ */
50
+ export const STEP_TABLE_PARENTS: ReadonlyMap<string, string> = new Map([
51
+ [traceStep.$name, trace.$name],
52
+ [traceStepRetained.$name, traceRetained.$name],
53
+ ])
@@ -0,0 +1,83 @@
1
+ // `trace.tree`: every hot trace sharing a root, with its steps.
2
+
3
+ import { sql } from '../../data/db/sql.js'
4
+ import type { DB } from '../../data/db/index.js'
5
+
6
+ /** One step of a trace. `ref` is the flow step's `path:symbol`, or `external:<name>` for a recorded or point-event step. */
7
+ export interface TraceStepNode {
8
+ readonly id: string
9
+ readonly parentStepId: string | null
10
+ readonly ref: string
11
+ readonly status: 'ok' | 'error'
12
+ readonly startedAt: Date
13
+ readonly completedAt: Date | null
14
+ /** The step's captured inputs (one entry per captured argument), or `null` when none were captured. */
15
+ readonly capturedInputs: unknown
16
+ readonly error: unknown
17
+ }
18
+
19
+ /** One trace of the tree, with its steps ordered by `seq`. */
20
+ export interface TraceNode {
21
+ readonly id: string
22
+ readonly parentId: string | null
23
+ readonly entryKind: 'http' | 'job' | 'cron' | 'test'
24
+ readonly tenant: string | null
25
+ readonly requestId: string | null
26
+ readonly startedAt: Date
27
+ readonly steps: readonly TraceStepNode[]
28
+ }
29
+
30
+ /** The traces that share a root id, ordered by when they opened. */
31
+ export interface TraceTree {
32
+ readonly traces: readonly TraceNode[]
33
+ }
34
+
35
+ const str = (v: unknown): string | null => (v === null || v === undefined ? null : String(v))
36
+ const date = (v: unknown): Date => (v instanceof Date ? v : new Date(String(v)))
37
+
38
+ /**
39
+ * Reads the hot `trace` and `trace_step` rows whose root is `rootId`: the
40
+ * request's trace and the traces of the jobs it queued. Rows already moved to
41
+ * the retained tables are not read. The read runs on `db` as given, so the
42
+ * tables' tenant policies apply: a connection with a tenant setting sees that
43
+ * tenant's rows, and only an unrestricted one (the table owner or a role that
44
+ * bypasses row-level security, as in tests) sees every tenant's. An unknown
45
+ * root returns no traces.
46
+ */
47
+ export async function tree(db: DB, rootId: string): Promise<TraceTree> {
48
+ const traces = await db.execute(sql`
49
+ SELECT "id", "parent_id", "entry_kind", "tenant_id", "request_id", "opened_at"
50
+ FROM "trace" WHERE "root_id" = ${rootId}::uuid ORDER BY "opened_at", "id"`)
51
+ if (traces.length === 0) return { traces: [] }
52
+ const steps = await db.execute(sql`
53
+ SELECT s."trace_id", s."id", s."parent_step_id", s."flow_step_ref", s."status", s."started_at",
54
+ s."completed_at", s."captured_inputs", s."error"
55
+ FROM "trace_step" s JOIN "trace" t ON t."id" = s."trace_id" AND t."opened_day" = s."trace_day"
56
+ WHERE t."root_id" = ${rootId}::uuid ORDER BY s."trace_id", s."seq"`)
57
+ const byTrace = new Map<string, TraceStepNode[]>()
58
+ for (const r of steps) {
59
+ const list = byTrace.get(String(r['trace_id'])) ?? []
60
+ list.push({
61
+ id: String(r['id']),
62
+ parentStepId: str(r['parent_step_id']),
63
+ ref: String(r['flow_step_ref']),
64
+ status: r['status'] as 'ok' | 'error',
65
+ startedAt: date(r['started_at']),
66
+ completedAt: r['completed_at'] === null ? null : date(r['completed_at']),
67
+ capturedInputs: r['captured_inputs'],
68
+ error: r['error'],
69
+ })
70
+ byTrace.set(String(r['trace_id']), list)
71
+ }
72
+ return {
73
+ traces: traces.map(r => ({
74
+ id: String(r['id']),
75
+ parentId: str(r['parent_id']),
76
+ entryKind: r['entry_kind'] as TraceNode['entryKind'],
77
+ tenant: str(r['tenant_id']),
78
+ requestId: str(r['request_id']),
79
+ startedAt: date(r['opened_at']),
80
+ steps: byTrace.get(String(r['id'])) ?? [],
81
+ })),
82
+ }
83
+ }
@@ -0,0 +1,76 @@
1
+ // Copy-on-error: when a trace ends badly (error / truncated / expired), the hot
2
+ // `trace` / `trace_step` partitions it lives in will be dropped on the normal
3
+ // `hotRetentionDays` schedule. Before that happens the errored trace — and its
4
+ // ancestry spine up to the root — is copied into the cold `trace_retained` /
5
+ // `trace_step_retained` tables, which keep the longer `errorRetentionDays`
6
+ // window.
7
+ //
8
+ // Only the parent chain is followed (`parent_id`): not siblings, not the step
9
+ // tree (`parent_step_id`). The spine is what you need to read an errored trace
10
+ // in context. Each copied trace brings all of its own steps.
11
+ //
12
+ // The copy is idempotent — `ON CONFLICT DO NOTHING` against each cold table's
13
+ // composite primary key — so re-running after a crash, or copying a trace whose
14
+ // ancestor was already retained by an earlier error, is a no-op.
15
+
16
+ import { sql } from '../../data/db/sql.js'
17
+ import type { DB } from '../../data/db/index.js'
18
+ import { quoteIdentifier } from '../../data/db/identifiers.js'
19
+ import { withMaintenance } from '../../data/db/maintenance.js'
20
+ import { camelToSnake } from '../../data/domain/naming.js'
21
+ import { traceFields } from '../schema/trace-fields.js'
22
+ import { traceStepFields } from '../schema/trace-step-fields.js'
23
+
24
+ export interface CopyOnErrorResult {
25
+ /** Rows newly inserted into `trace_retained` (rows already retained excluded). */
26
+ readonly traces: number
27
+ /** Rows newly inserted into `trace_step_retained`. */
28
+ readonly steps: number
29
+ }
30
+
31
+ function columnList(keys: string[], label: string, prefix = ''): string {
32
+ return keys.map(k => `${prefix}${quoteIdentifier(camelToSnake(k), label)}`).join(', ')
33
+ }
34
+
35
+ const TRACE_COLUMNS = columnList(Object.keys(traceFields), 'trace column')
36
+ const TRACE_STEP_COLUMNS = columnList(Object.keys(traceStepFields), 'trace step column')
37
+ const TRACE_STEP_COLUMNS_FROM_STEP = columnList(Object.keys(traceStepFields), 'trace step column', 's.')
38
+
39
+ /**
40
+ * Copy an errored trace and its parent spine into the cold retained tables.
41
+ *
42
+ * `traceId` is the trace that ended badly. Its ancestry is walked through
43
+ * `parent_id` to the root; every trace on that spine, plus all of their steps,
44
+ * is inserted into `trace_retained` / `trace_step_retained`. Returns the count
45
+ * of rows actually inserted — zero for both when everything was already
46
+ * retained, or when `traceId` does not exist.
47
+ */
48
+ export async function copyTraceOnError(db: DB, traceId: string): Promise<CopyOnErrorResult> {
49
+ // Reads the whole parent spine, which may cross tenants, so the copy is a maintenance pass.
50
+ const rows = await withMaintenance(db, tx => tx.execute(sql`
51
+ WITH RECURSIVE spine AS (
52
+ SELECT * FROM "trace" WHERE "id" = ${traceId}
53
+ UNION
54
+ SELECT t.* FROM "trace" t JOIN spine ON t."id" = spine."parent_id"
55
+ ),
56
+ copied_traces AS (
57
+ INSERT INTO "trace_retained" (${sql.raw(TRACE_COLUMNS)})
58
+ SELECT ${sql.raw(TRACE_COLUMNS)} FROM spine
59
+ ON CONFLICT ("id", "opened_day") DO NOTHING
60
+ RETURNING "id"
61
+ ),
62
+ copied_steps AS (
63
+ INSERT INTO "trace_step_retained" (${sql.raw(TRACE_STEP_COLUMNS)})
64
+ SELECT ${sql.raw(TRACE_STEP_COLUMNS_FROM_STEP)}
65
+ FROM "trace_step" s JOIN spine ON s."trace_id" = spine."id"
66
+ ON CONFLICT ("id", "trace_day") DO NOTHING
67
+ RETURNING "id"
68
+ )
69
+ SELECT
70
+ (SELECT count(*) FROM copied_traces)::int AS traces,
71
+ (SELECT count(*) FROM copied_steps)::int AS steps
72
+ `))
73
+
74
+ const row = rows[0]!
75
+ return { traces: row['traces'] as number, steps: row['steps'] as number }
76
+ }
@@ -0,0 +1,54 @@
1
+ // Q7 expiry sweep. A trace must not outlive its own oldest day-partition: if
2
+ // a trace is still `open` past `expires_at` (stamped as `opened_at +
3
+ // hotRetentionDays` at entry), the entry leaked or the job hung — the process
4
+ // that opened the trace may be long dead, so there is no in-memory buffer to
5
+ // flush. The sweep force-closes those orphans at the database level: stamps
6
+ // `status = 'expired'` and `closed_at`, then copies the trace to the cold set
7
+ // (treated as an error for Q4) before the next partition retirement drops the
8
+ // hot row.
9
+ //
10
+ // `force_now` is injectable so the sweep is testable without mocking the
11
+ // clock — production calls pass nothing and use `NOW()`.
12
+
13
+ import { sql } from '../../data/db/sql.js'
14
+ import type { DB } from '../../data/db/index.js'
15
+ import { getBaseLogger } from '../../core/logging/index.js'
16
+ import { withMaintenance } from '../../data/db/maintenance.js'
17
+ import { copyTraceOnError } from '../retain/copy-on-error.js'
18
+
19
+ export interface ExpireStaleTracesResult {
20
+ /** Trace rows force-closed by this sweep (`open` past `expires_at`). */
21
+ readonly expired: number
22
+ /** Rows newly inserted into `trace_retained` across all expired traces. */
23
+ readonly retained: number
24
+ }
25
+
26
+ /** Force-closes every trace whose `expires_at` has passed; copies each to the cold set. */
27
+ export async function expireStaleTraces(
28
+ db: DB,
29
+ now: Date = new Date(),
30
+ ): Promise<ExpireStaleTracesResult> {
31
+ // postgres.js's raw `sql` parameters carry no column-type hint, so a Date
32
+ // binds as an unsupported type for `timestamptz`. The boundary cast to an
33
+ // ISO string keeps the production signature on `Date` without losing
34
+ // precision (compared as a literal, Postgres parses it back to `timestamptz`).
35
+ const nowIso = now.toISOString()
36
+ // Every tenant's traces, so the sweep is a maintenance pass.
37
+ const rows = await withMaintenance(db, tx => tx.execute(sql`
38
+ UPDATE "trace"
39
+ SET "status" = 'expired', "closed_at" = ${nowIso}
40
+ WHERE "status" = 'open' AND "expires_at" <= ${nowIso}
41
+ RETURNING "id"
42
+ `))
43
+ const ids = rows.map(r => r['id'] as string)
44
+ if (ids.length === 0) return { expired: 0, retained: 0 }
45
+
46
+ getBaseLogger().error(
47
+ { count: ids.length, traceIds: ids },
48
+ 'Force-closed expired traces — entries leaked or hung past their hot retention window',
49
+ )
50
+
51
+ const copyResults = await Promise.all(ids.map(id => copyTraceOnError(db, id)))
52
+ const retained = copyResults.reduce((sum, r) => sum + r.traces, 0)
53
+ return { expired: ids.length, retained }
54
+ }
@@ -0,0 +1,147 @@
1
+ // `__flowStep` — the value-wrapping runtime for a flow step. The build
2
+ // transformer (component 5) renames each documented function and rebinds its
3
+ // public name through this wrapper: `export const runJob = __flowStep(meta,
4
+ // runJobImpl)`. No body is rewritten; the wrapper is the whole instrumentation.
5
+ //
6
+ // Off the traced path it is a pass-through with one `getContext()` lookup and a
7
+ // branch — there is no active Flow, or the Flow opened no trace, so there is
8
+ // nothing to record. On the traced path it brackets the implementation with a
9
+ // `trace_step`: a `seq`, a parent link, start/end timing, and the outcome.
10
+ // Once a trace truncates (Q7), every later step takes the pass-through path
11
+ // too, so a truncated trace costs exactly what an untraced one does.
12
+ //
13
+ // Tier-2 input capture (Q5) runs at `begin` time, before the implementation
14
+ // gets a chance to mutate the arguments. Each parameter's projection — baked
15
+ // into `meta.capture` by the transformer — turns its argument into a
16
+ // trace-safe payload, which the bounded serializer caps for depth, fan-out,
17
+ // string length, and redaction before staging onto `trace_step.captured_inputs`.
18
+ // The trace's `captureInputs` kill-switch (resolved at trace open from
19
+ // `config.trace.captureInputs`) suppresses the whole capture path while
20
+ // leaving Tier-1 (timing, status, error) untouched.
21
+ //
22
+ // `meta` is a literal baked in at transform time — the wrapper never computes
23
+ // the step's identity.
24
+
25
+ import { getContext } from '../../request/context/store.js'
26
+ import { serializeForTrace } from '../capture/bounded-serializer.js'
27
+ import { isThenable } from './thenable.js'
28
+ import { truncateTrace } from './truncate-trace.js'
29
+ import { emitReadTouches } from '../../data/write/audit/read-touches.js'
30
+ import type { CaptureProjection, FlowStepMeta } from './step-meta.js'
31
+ import type { BegunStep } from './step-buffer.js'
32
+ import type { Flow } from '../../request/context/types.js'
33
+
34
+ /* eslint-disable @typescript-eslint/no-explicit-any -- a transparent wrapper must accept and return the implementation's exact signature */
35
+ type AnyFunction = (...args: any[]) => any
36
+
37
+ /**
38
+ * Wraps `impl` so that, under an active traced Flow, each call records a `trace_step`.
39
+ *
40
+ * A function documented with `@flow_step` (and `@touches Entity:verb`) is wrapped automatically: under `pipework test` and the vitest preset, and under `pipework dev` and `pipework serve`. An app built with plain `tsc` gets no wrapping: run it through `pipework serve`, or call `__flowStep` by hand.
41
+ *
42
+ * A write under a step with `@touches` is audited only under the touches whose entity is the written table, one `audit_record` per affected row per selected touch. A row's verb is `create` (an insert, or an upsert row that did not exist), `update` or `delete`; it is recorded under the touches with exactly that verb, else under the touches with a custom verb (not create/update/delete), else under all the entity's touches. A write also counts as written for the step's other create/update/delete touches on the entity, and for the same touch on enclosing steps. A touch's `Entity` matches a table when the definition declares `define(name, fields, { auditEntity })` equal to `Entity` exactly; otherwise when the names agree ignoring case and underscores, with the table name optionally plural (`Version` matches `version` and `versions`; `DocumentVersion` matches `document_versions`). A write to a table no touch matches is not audited. A touch that no write of the step was audited under gets a read row (`before` and `after` null) when the step completes. A write under a step with a touch whose entity matches no defined table throws, naming the closest table names. `.returning()` returns the same rows with or without an audited step.
43
+ */
44
+ export function __flowStep<F extends AnyFunction>(meta: FlowStepMeta, impl: F): F {
45
+ function traced(this: unknown, ...args: Parameters<F>): ReturnType<F> {
46
+ const flow = getContext()
47
+ if (flow === undefined || flow.trace === null) {
48
+ return impl.apply(this, args) as ReturnType<F>
49
+ }
50
+ const ctx = flow.trace
51
+ const buffer = ctx.buffer
52
+ if (buffer.truncated) {
53
+ return impl.apply(this, args) as ReturnType<F>
54
+ }
55
+
56
+ const capturedInputs = buffer.captureInputs && meta.capture !== undefined
57
+ ? captureArgs(args, meta.capture)
58
+ : null
59
+
60
+ const begun = buffer.begin(meta.ref, capturedInputs, meta.touches ?? [])
61
+ // `begin` returns null for the call that blows the step cap — that call,
62
+ // and every step after it, runs untraced. The transition fires `truncateTrace`
63
+ // exactly once: the `buffer.truncated` short-circuit above catches every
64
+ // subsequent call before it reaches `begin`.
65
+ if (begun === null) {
66
+ void truncateTrace(flow.instance, ctx)
67
+ return impl.apply(this, args) as ReturnType<F>
68
+ }
69
+
70
+ let result: unknown
71
+ try {
72
+ result = impl.apply(this, args)
73
+ } catch (err) {
74
+ buffer.complete(begun, 'error', err)
75
+ throw err
76
+ }
77
+
78
+ if (isThenable(result)) {
79
+ return result.then(
80
+ async (value: unknown) => {
81
+ buffer.complete(begun, 'ok', null)
82
+ await emitReadTouchesIfNeeded(flow, begun)
83
+ return value
84
+ },
85
+ (err: unknown) => {
86
+ buffer.complete(begun, 'error', err)
87
+ throw err
88
+ },
89
+ ) as ReturnType<F>
90
+ }
91
+
92
+ buffer.complete(begun, 'ok', null)
93
+ // Sync impl: can't change the wrapper's return type to Promise, so fire-and-
94
+ // forget. The audit emitter swallows its own errors, so this won't yield an
95
+ // unhandled rejection; the trade-off is that a sync `@touches` step's audit
96
+ // row may land after control has returned to the caller. Sync impls under
97
+ // `@touches` are rare anyway (pipe.* writes are all async).
98
+ void emitReadTouchesIfNeeded(flow, begun)
99
+ return result as ReturnType<F>
100
+ }
101
+
102
+ return traced as F
103
+ }
104
+ /* eslint-enable @typescript-eslint/no-explicit-any */
105
+
106
+ /**
107
+ * Read-touches gate. The CTE-form write path already covered the touches it wrote
108
+ * (recorded via `markWrote(touch)`); this fires for the rest — touches
109
+ * no `pipe.*` write of the step was audited under. Empty
110
+ * `touches` means no audit projection at all and short-circuits earlier in
111
+ * the emitter.
112
+ */
113
+ function emitReadTouchesIfNeeded(flow: Flow, begun: BegunStep): Promise<void> {
114
+ if (begun.touches.every(t => begun.wroteTouches.has(t))) return Promise.resolve()
115
+ return emitReadTouches(flow, begun)
116
+ }
117
+
118
+ /**
119
+ * Projects + bounded-serializes one captured payload per parameter, in
120
+ * declaration order. A `null` projection slot means the parameter has no
121
+ * registry-derived projection (primitive, `any`, or no `.traceSafe()` entry)
122
+ * and the raw arg is handed straight to the serializer. A projection that
123
+ * returns `undefined` is preserved as a `null` slot — fail-closed: an unsafe
124
+ * structured type with no marked-safe fields contributes no payload.
125
+ */
126
+ function captureArgs(
127
+ args: readonly unknown[],
128
+ projections: ReadonlyArray<CaptureProjection | null>,
129
+ ): unknown[] {
130
+ const out: unknown[] = []
131
+ // Pair by parameter index. Extra args (a variadic tail without a matching
132
+ // projection) fall through to the raw-serializer path; extra projections
133
+ // (impl invoked with fewer than declared args) project `undefined` — both
134
+ // paths converge on the bounded serializer's `undefined` handling.
135
+ const count = Math.max(args.length, projections.length)
136
+ for (let i = 0; i < count; i++) {
137
+ const projection = projections[i] ?? null
138
+ const raw = args[i]
139
+ const projected = projection === null ? raw : projection(raw)
140
+ if (projected === undefined) {
141
+ out.push(null)
142
+ continue
143
+ }
144
+ out.push(serializeForTrace(projected))
145
+ }
146
+ return out
147
+ }
@@ -0,0 +1,31 @@
1
+ // Batch-writes a buffered set of `trace_step` rows. The write is fire-and-
2
+ // forget — the close path doesn't block on it, and a failure must not break
3
+ // the request: a missing step row is a degraded trace, not a degraded user
4
+ // flow. Errors land in the base logger so an operator can see what was lost.
5
+ //
6
+ // The write goes through `instance.pool` directly, never the request
7
+ // transaction — an errored request rolls back, but its trace steps must
8
+ // survive to be inspected.
9
+
10
+ import type { Manifold } from '../../core/pipework.js'
11
+ import { getBaseLogger } from '../../core/logging/index.js'
12
+ import { recordFaultFor, faultMessage } from '../../infra/alerts/faults.js'
13
+ import { traceStep } from '../schema/trace-step.js'
14
+ import { trackTraceWrite } from './pending-writes.js'
15
+ import type { PendingStep } from './step-buffer.js'
16
+
17
+ /** Inserts `steps` into `trace_step` in a single batch. Resolves once the write settles. */
18
+ export function flushSteps(instance: Manifold, steps: readonly PendingStep[]): Promise<void> {
19
+ if (steps.length === 0) return Promise.resolve()
20
+ const db = instance.pool.getOrCreate(instance.config.database()).drizzle
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Drizzle's insert needs the concrete runtime table type
22
+ return trackTraceWrite((db as any).insert(traceStep.table()).values([...steps])
23
+ .then(() => undefined)
24
+ .catch((err: unknown) => {
25
+ getBaseLogger().error(
26
+ { err, traceId: steps[0]!.traceId, steps: steps.length },
27
+ 'Failed to persist trace steps — the trace is missing step rows',
28
+ )
29
+ void recordFaultFor(instance, 'trace-steps-lost', `${String(steps.length)} trace step(s) not persisted: ${faultMessage(err)}`, { traceId: steps[0]!.traceId, steps: steps.length })
30
+ }))
31
+ }
@@ -0,0 +1,54 @@
1
+ // Trace writes are fire-and-forget; this tracks the ones in flight so the test
2
+ // harness can wait for them before it ends the connection they write through.
3
+
4
+ import { getBaseLogger } from '../../core/logging/index.js'
5
+
6
+ // Process-global so writes tracked by any copy of this module (loaded by
7
+ // `vi.resetModules()` / `vi.isolateModules`) are visible to the harness's settle.
8
+ const SLOT = Symbol.for('pipework.traceWrites')
9
+ const slots = globalThis as unknown as Record<symbol, Set<Promise<void>> | undefined>
10
+ const pending: Set<Promise<void>> = (slots[SLOT] ??= new Set<Promise<void>>())
11
+
12
+ /** Records `write` as in flight until it settles; returns it unchanged. */
13
+ export function trackTraceWrite(write: Promise<void>): Promise<void> {
14
+ pending.add(write)
15
+ const forget = (): void => { pending.delete(write) }
16
+ write.then(forget, forget)
17
+ return write
18
+ }
19
+
20
+ /** Resolves once no trace write is in flight, including writes started by earlier ones. */
21
+ export async function settleTraceWrites(): Promise<void> {
22
+ while (pending.size > 0) await Promise.allSettled([...pending])
23
+ }
24
+
25
+ /** How many trace writes are in flight now. */
26
+ export function pendingTraceWriteCount(): number {
27
+ return pending.size
28
+ }
29
+
30
+ export const TRACE_SETTLE_TIMEOUT_MS = 30_000
31
+
32
+ /** The harness's teardown hooks' own timeout: room for a full settle plus the teardown itself. */
33
+ export const TEARDOWN_HOOK_TIMEOUT_MS = TRACE_SETTLE_TIMEOUT_MS + 30_000
34
+
35
+ /**
36
+ * Waits for in-flight trace writes for at most `timeoutMs`. On expiry it warns once with
37
+ * the number still in flight and returns, so teardown proceeds anyway.
38
+ */
39
+ export async function settleTraceWritesBounded(timeoutMs: number = TRACE_SETTLE_TIMEOUT_MS): Promise<void> {
40
+ let timer: NodeJS.Timeout | undefined
41
+ const expired = Symbol('expired')
42
+ const timeout = new Promise<typeof expired>(resolve => { timer = setTimeout(() => resolve(expired), timeoutMs) })
43
+ try {
44
+ const outcome = await Promise.race([settleTraceWrites(), timeout])
45
+ if (outcome === expired) {
46
+ getBaseLogger().warn(
47
+ { inFlight: pendingTraceWriteCount(), timeoutMs },
48
+ `${pendingTraceWriteCount()} trace write(s) still in flight after ${timeoutMs} ms; test teardown proceeds anyway`,
49
+ )
50
+ }
51
+ } finally {
52
+ clearTimeout(timer)
53
+ }
54
+ }