nexus-ai-pro 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/API_STABILITY.md +271 -0
  2. package/CHANGELOG.md +330 -1
  3. package/README.md +18 -4
  4. package/SECURITY.md +209 -0
  5. package/dist/adapter-kit/contracts.d.ts +87 -0
  6. package/dist/adapter-kit/contracts.js +237 -0
  7. package/dist/adapter-kit/errors.d.ts +39 -0
  8. package/dist/adapter-kit/errors.js +52 -0
  9. package/dist/adapter-kit/index.d.ts +144 -0
  10. package/dist/adapter-kit/index.js +178 -0
  11. package/dist/adapter-kit/semver.d.ts +12 -0
  12. package/dist/adapter-kit/semver.js +55 -0
  13. package/dist/agent/middleware/pii.js +2 -33
  14. package/dist/context-hub/hub.d.ts +53 -0
  15. package/dist/context-hub/hub.js +108 -3
  16. package/dist/context-hub/index.d.ts +2 -1
  17. package/dist/context-hub/index.js +2 -1
  18. package/dist/context-hub/signing.d.ts +95 -0
  19. package/dist/context-hub/signing.js +88 -0
  20. package/dist/core/secure-stream.js +4 -3
  21. package/dist/doctor/index.d.ts +4 -2
  22. package/dist/doctor/index.js +29 -0
  23. package/dist/embeddings/adapters.js +2 -1
  24. package/dist/evals/judge.js +2 -5
  25. package/dist/evaluate/cache.d.ts +0 -14
  26. package/dist/evaluate/cache.js +0 -30
  27. package/dist/evaluate/file-cache.d.ts +15 -0
  28. package/dist/evaluate/file-cache.js +30 -0
  29. package/dist/evaluate/index.d.ts +2 -1
  30. package/dist/evaluate/index.js +2 -1
  31. package/dist/evaluate/review.js +2 -2
  32. package/dist/evaluate/run.js +2 -2
  33. package/dist/evaluate/threads.d.ts +187 -0
  34. package/dist/evaluate/threads.js +187 -0
  35. package/dist/evaluate/version.js +3 -3
  36. package/dist/graph/graph.js +2 -2
  37. package/dist/graph/node-cache.js +3 -3
  38. package/dist/hallucination/rag.d.ts +4 -1
  39. package/dist/hallucination/rag.js +6 -1
  40. package/dist/images/asset-stores.js +2 -3
  41. package/dist/images/asset-support.js +2 -2
  42. package/dist/images/assets.js +1 -2
  43. package/dist/images/evals.js +4 -4
  44. package/dist/insights/proposals.js +1 -2
  45. package/dist/insights/regressions.d.ts +26 -2
  46. package/dist/insights/regressions.js +129 -3
  47. package/dist/loaders/git.js +8 -1
  48. package/dist/loaders/web.js +7 -1
  49. package/dist/mcp/client.d.ts +14 -0
  50. package/dist/mcp/client.js +59 -1
  51. package/dist/mcp/registry.d.ts +6 -0
  52. package/dist/mcp/registry.js +7 -0
  53. package/dist/operations/adapters.d.ts +2 -1
  54. package/dist/operations/runner.js +2 -0
  55. package/dist/operations/stats.js +11 -4
  56. package/dist/postgres/index.d.ts +2 -1
  57. package/dist/postgres/index.js +4 -0
  58. package/dist/postgres/operations.js +11 -4
  59. package/dist/postgres/store.d.ts +7 -0
  60. package/dist/postgres/store.js +21 -0
  61. package/dist/postgres/tenancy.d.ts +43 -0
  62. package/dist/postgres/tenancy.js +71 -0
  63. package/dist/prompts/file.js +28 -11
  64. package/dist/protocols/a2a.d.ts +235 -0
  65. package/dist/protocols/a2a.js +386 -0
  66. package/dist/protocols/acp.d.ts +87 -0
  67. package/dist/protocols/acp.js +322 -0
  68. package/dist/protocols/ag-ui.d.ts +120 -0
  69. package/dist/protocols/ag-ui.js +180 -0
  70. package/dist/protocols/shared.d.ts +80 -0
  71. package/dist/protocols/shared.js +49 -0
  72. package/dist/providers/anthropic.js +1 -0
  73. package/dist/providers/cohere.js +2 -2
  74. package/dist/providers/google.js +2 -11
  75. package/dist/providers/openai.js +1 -0
  76. package/dist/rag/file-ingestion.js +15 -9
  77. package/dist/runtime/detect.d.ts +17 -0
  78. package/dist/runtime/detect.js +16 -0
  79. package/dist/runtime/index.d.ts +19 -0
  80. package/dist/runtime/index.js +7 -0
  81. package/dist/security/injection-detector.d.ts +2 -0
  82. package/dist/security/injection-detector.js +7 -1
  83. package/dist/security/input-guard.js +5 -2
  84. package/dist/security/output-guard.js +8 -4
  85. package/dist/security/pii-detector.js +22 -6
  86. package/dist/security/prompt-hardening.js +6 -2
  87. package/dist/security/semantic-injection-classifier.d.ts +2 -1
  88. package/dist/security/semantic-injection-classifier.js +31 -35
  89. package/dist/security/upload-scanner.d.ts +8 -0
  90. package/dist/security/upload-scanner.js +51 -9
  91. package/dist/server/deployments.d.ts +188 -11
  92. package/dist/server/deployments.js +474 -36
  93. package/dist/server/metrics.d.ts +2 -0
  94. package/dist/server/metrics.js +7 -0
  95. package/dist/server/runs.d.ts +18 -1
  96. package/dist/server/runs.js +66 -7
  97. package/dist/server/server.js +9 -1
  98. package/dist/server/state.d.ts +12 -2
  99. package/dist/server/state.js +15 -0
  100. package/dist/sqlite/operations.js +15 -4
  101. package/dist/sqlite/store.d.ts +7 -0
  102. package/dist/sqlite/store.js +28 -0
  103. package/dist/store/memory.d.ts +8 -0
  104. package/dist/store/memory.js +12 -1
  105. package/dist/store/redis.d.ts +13 -0
  106. package/dist/store/redis.js +38 -0
  107. package/dist/testing/record.js +2 -2
  108. package/dist/tracing/instrument.js +1 -0
  109. package/dist/tracing/stores.js +2 -1
  110. package/dist/tracing/tracer.d.ts +4 -0
  111. package/dist/tracing/tracer.js +8 -2
  112. package/dist/types/config.d.ts +20 -0
  113. package/dist/types/operations.d.ts +7 -0
  114. package/dist/types/server.d.ts +67 -2
  115. package/dist/types/store.d.ts +9 -0
  116. package/dist/utils/base64.d.ts +4 -0
  117. package/dist/utils/base64.js +21 -0
  118. package/dist/utils/checksums.d.ts +22 -0
  119. package/dist/utils/checksums.js +39 -0
  120. package/dist/utils/ids.d.ts +8 -0
  121. package/dist/utils/ids.js +26 -2
  122. package/dist/utils/sha256.d.ts +22 -0
  123. package/dist/utils/sha256.js +120 -0
  124. package/dist/version.d.ts +1 -1
  125. package/dist/version.js +1 -1
  126. package/dist-cjs/adapter-kit/contracts.d.ts +87 -0
  127. package/dist-cjs/adapter-kit/contracts.js +243 -0
  128. package/dist-cjs/adapter-kit/errors.d.ts +39 -0
  129. package/dist-cjs/adapter-kit/errors.js +57 -0
  130. package/dist-cjs/adapter-kit/index.d.ts +144 -0
  131. package/dist-cjs/adapter-kit/index.js +194 -0
  132. package/dist-cjs/adapter-kit/semver.d.ts +12 -0
  133. package/dist-cjs/adapter-kit/semver.js +59 -0
  134. package/dist-cjs/agent/middleware/pii.js +4 -35
  135. package/dist-cjs/context-hub/hub.d.ts +53 -0
  136. package/dist-cjs/context-hub/hub.js +110 -4
  137. package/dist-cjs/context-hub/index.d.ts +2 -1
  138. package/dist-cjs/context-hub/index.js +7 -1
  139. package/dist-cjs/context-hub/signing.d.ts +95 -0
  140. package/dist-cjs/context-hub/signing.js +96 -0
  141. package/dist-cjs/core/secure-stream.js +4 -3
  142. package/dist-cjs/doctor/index.d.ts +4 -2
  143. package/dist-cjs/doctor/index.js +29 -0
  144. package/dist-cjs/embeddings/adapters.js +2 -1
  145. package/dist-cjs/evals/judge.js +2 -5
  146. package/dist-cjs/evaluate/cache.d.ts +0 -14
  147. package/dist-cjs/evaluate/cache.js +1 -65
  148. package/dist-cjs/evaluate/file-cache.d.ts +15 -0
  149. package/dist-cjs/evaluate/file-cache.js +67 -0
  150. package/dist-cjs/evaluate/index.d.ts +2 -1
  151. package/dist-cjs/evaluate/index.js +3 -2
  152. package/dist-cjs/evaluate/review.js +2 -2
  153. package/dist-cjs/evaluate/run.js +2 -2
  154. package/dist-cjs/evaluate/threads.d.ts +187 -0
  155. package/dist-cjs/evaluate/threads.js +198 -0
  156. package/dist-cjs/evaluate/version.js +3 -3
  157. package/dist-cjs/graph/graph.js +2 -2
  158. package/dist-cjs/graph/node-cache.js +3 -3
  159. package/dist-cjs/hallucination/rag.d.ts +4 -1
  160. package/dist-cjs/hallucination/rag.js +6 -1
  161. package/dist-cjs/images/asset-stores.js +2 -3
  162. package/dist-cjs/images/asset-support.js +2 -2
  163. package/dist-cjs/images/assets.js +1 -2
  164. package/dist-cjs/images/evals.js +4 -4
  165. package/dist-cjs/insights/proposals.js +1 -2
  166. package/dist-cjs/insights/regressions.d.ts +26 -2
  167. package/dist-cjs/insights/regressions.js +129 -3
  168. package/dist-cjs/loaders/git.js +8 -1
  169. package/dist-cjs/loaders/web.js +7 -1
  170. package/dist-cjs/mcp/client.d.ts +14 -0
  171. package/dist-cjs/mcp/client.js +60 -1
  172. package/dist-cjs/mcp/registry.d.ts +6 -0
  173. package/dist-cjs/mcp/registry.js +7 -0
  174. package/dist-cjs/operations/adapters.d.ts +2 -1
  175. package/dist-cjs/operations/runner.js +2 -0
  176. package/dist-cjs/operations/stats.js +11 -4
  177. package/dist-cjs/postgres/index.d.ts +2 -1
  178. package/dist-cjs/postgres/index.js +8 -1
  179. package/dist-cjs/postgres/operations.js +11 -4
  180. package/dist-cjs/postgres/store.d.ts +7 -0
  181. package/dist-cjs/postgres/store.js +21 -0
  182. package/dist-cjs/postgres/tenancy.d.ts +43 -0
  183. package/dist-cjs/postgres/tenancy.js +110 -0
  184. package/dist-cjs/prompts/file.js +28 -11
  185. package/dist-cjs/protocols/a2a.d.ts +235 -0
  186. package/dist-cjs/protocols/a2a.js +393 -0
  187. package/dist-cjs/protocols/acp.d.ts +87 -0
  188. package/dist-cjs/protocols/acp.js +326 -0
  189. package/dist-cjs/protocols/ag-ui.d.ts +120 -0
  190. package/dist-cjs/protocols/ag-ui.js +186 -0
  191. package/dist-cjs/protocols/shared.d.ts +80 -0
  192. package/dist-cjs/protocols/shared.js +59 -0
  193. package/dist-cjs/providers/anthropic.js +1 -0
  194. package/dist-cjs/providers/cohere.js +2 -2
  195. package/dist-cjs/providers/google.js +3 -12
  196. package/dist-cjs/providers/openai.js +1 -0
  197. package/dist-cjs/rag/file-ingestion.js +14 -8
  198. package/dist-cjs/runtime/detect.d.ts +17 -0
  199. package/dist-cjs/runtime/detect.js +19 -0
  200. package/dist-cjs/runtime/index.d.ts +19 -0
  201. package/dist-cjs/runtime/index.js +31 -0
  202. package/dist-cjs/security/injection-detector.d.ts +2 -0
  203. package/dist-cjs/security/injection-detector.js +7 -1
  204. package/dist-cjs/security/input-guard.js +5 -2
  205. package/dist-cjs/security/output-guard.js +8 -4
  206. package/dist-cjs/security/pii-detector.js +22 -6
  207. package/dist-cjs/security/prompt-hardening.js +6 -2
  208. package/dist-cjs/security/semantic-injection-classifier.d.ts +2 -1
  209. package/dist-cjs/security/semantic-injection-classifier.js +31 -35
  210. package/dist-cjs/security/upload-scanner.d.ts +8 -0
  211. package/dist-cjs/security/upload-scanner.js +53 -9
  212. package/dist-cjs/server/deployments.d.ts +188 -11
  213. package/dist-cjs/server/deployments.js +474 -36
  214. package/dist-cjs/server/metrics.d.ts +2 -0
  215. package/dist-cjs/server/metrics.js +8 -0
  216. package/dist-cjs/server/runs.d.ts +18 -1
  217. package/dist-cjs/server/runs.js +65 -6
  218. package/dist-cjs/server/server.js +9 -1
  219. package/dist-cjs/server/state.d.ts +12 -2
  220. package/dist-cjs/server/state.js +15 -0
  221. package/dist-cjs/sqlite/operations.js +15 -4
  222. package/dist-cjs/sqlite/store.d.ts +7 -0
  223. package/dist-cjs/sqlite/store.js +28 -0
  224. package/dist-cjs/store/memory.d.ts +8 -0
  225. package/dist-cjs/store/memory.js +12 -1
  226. package/dist-cjs/store/redis.d.ts +13 -0
  227. package/dist-cjs/store/redis.js +38 -0
  228. package/dist-cjs/testing/record.js +2 -2
  229. package/dist-cjs/tracing/instrument.js +1 -0
  230. package/dist-cjs/tracing/stores.js +2 -1
  231. package/dist-cjs/tracing/tracer.d.ts +4 -0
  232. package/dist-cjs/tracing/tracer.js +8 -2
  233. package/dist-cjs/types/config.d.ts +20 -0
  234. package/dist-cjs/types/operations.d.ts +7 -0
  235. package/dist-cjs/types/server.d.ts +67 -2
  236. package/dist-cjs/types/store.d.ts +9 -0
  237. package/dist-cjs/utils/base64.d.ts +4 -0
  238. package/dist-cjs/utils/base64.js +25 -0
  239. package/dist-cjs/utils/checksums.d.ts +22 -0
  240. package/dist-cjs/utils/checksums.js +46 -0
  241. package/dist-cjs/utils/ids.d.ts +8 -0
  242. package/dist-cjs/utils/ids.js +28 -2
  243. package/dist-cjs/utils/sha256.d.ts +22 -0
  244. package/dist-cjs/utils/sha256.js +125 -0
  245. package/dist-cjs/version.d.ts +1 -1
  246. package/dist-cjs/version.js +1 -1
  247. package/llms.txt +5 -2
  248. package/package.json +102 -6
package/API_STABILITY.md CHANGED
@@ -41,6 +41,263 @@ Both are covered by this policy:
41
41
  Deep imports into `dist`, `dist-cjs`, or `src` are not supported. Import only from `nexus-ai-pro` or
42
42
  one of its explicit subpaths.
43
43
 
44
+ ## 2.5 stage (2.5.0)
45
+
46
+ Everything 2.5 adds is stable from the start and additive.
47
+
48
+ New and stable:
49
+ - `putIfVersion()`, optional on `Store` and `ServerStateStore`, and its implementations;
50
+ `Deployments.atomicChanges`; `ScalingSnapshot.atomicChanges`;
51
+ - `nexus-ai-pro/postgres/tenancy`: `PostgresTenantUsage`, `PostgresTenantUsageOptions`,
52
+ `tenantUsageMigration()`, and `tenantUsageMigrations()`; the `tenancy` member of
53
+ `PostgresAdapter`;
54
+ - `OperationStoreFilter.kinds`, `OperationStoreStats.queuedByKind`, `RevisionRequest.queued`,
55
+ `RevisionChoice.local`, `ScalingSnapshot.queuedByRevision`, and the
56
+ `nexus_server_runs_queued_by_revision` metric.
57
+
58
+ - signing on `nexus-ai-pro/context-hub`: `ContextHubOptions.signer`, `keyring`, and `requireSignature`;
59
+ `ContextHub.verify()` and `ContextVerification`; `ContextBundle.signatures`; `ContextSignatureError`;
60
+ `generateContextKey()`, `ed25519Signer()`, `ed25519Keyring()`, `contextDigest()`, and the signing
61
+ types. The signed digest's format is `nexus-context-signature`, format version 1, and a later release
62
+ verifies it;
63
+ - `metadata.context` on a traced model call;
64
+ - on `nexus-ai-pro/server/deployments`, experimental with the rest of it: `BucketStrategy`,
65
+ `DeploymentRecord.bucketStrategy`, `RevisionedAssistantOptions.bucketStrategy`, the `bucketing`
66
+ change and `Deployments.bucketing()`, the strategy argument of `bucket()`; `recordRun()`,
67
+ `rollups()`, `flushRollups()`, `stats({ deployment })`, `DeploymentRollup`, `RevisionRollup`, and
68
+ `DeploymentsOptions.rollupMs`; `CanaryGuardOptions.from`. `ServerDeployments` gains an optional
69
+ `recordRun()`, and `RunManagerOptions.deployments`. The positions `fnv1a-v1` and `hash-v2` give a key
70
+ never change;
71
+ - the doctor's `settings` check; `RedisOperationStore.indexed`; `Tracer.store` and
72
+ `Tracer.incremental`;
73
+ - `nexus-ai-pro/evaluate/threads`, experimental: `simulatedUser()`, `scriptedUser()`,
74
+ `conversationTarget()`, `graphThreadAgent()`, `formatThread()`, `goalReached()`,
75
+ `goalCompletion()`, `turnCount()`, `turnScores()`, and their types. The score keys `goal_reached`,
76
+ `goal_completion`, `turns`, and `turn_score` are stable once the entry point graduates.
77
+
78
+ The studio now refuses, as the compatibility rules allow for security: a change whose body is not
79
+ `application/json`, with `415`; a body that is not a JSON object, with `400`; a body past
80
+ `maxBodyBytes`, with `413`; and a list `limit`, `hours`, or `days` past its ceiling, with `400`. With
81
+ accounts, only a bearer `Authorization` header stands in for the page token. The agent server refuses
82
+ an assistant or revision named after a built-in property, such as `constructor`. Also stable from
83
+ 2.5: `StudioOptions.maxBodyBytes`, `Studio.routes` and `StudioRoute`, and
84
+ `MemoryStudioJournalOptions.maxComments`.
85
+
86
+ ### Graduation
87
+
88
+ Two more surfaces leave experimental status in 2.5, by the same checklist as in 2.4. Every test named
89
+ here runs in CI.
90
+
91
+ **Deployments** (`nexus-ai-pro/server/deployments`):
92
+
93
+ | Requirement | Evidence |
94
+ | --- | --- |
95
+ | Conformance | Atomic changes on the memory server store and the memory, Redis, Postgres, and SQLite stores: `tests/atomic-deployments.test.ts`; routing, canaries, and guards: `tests/deployments.test.ts`, `tests/fair-canaries.test.ts`; revision pools: `tests/revision-pools.test.ts` |
96
+ | Crash recovery | A change is one compare-and-set write, so a crash leaves the old record or the new one; a drained replica hands its runs to another: `tests/deployments.test.ts`. A replica that dies loses at most its last `rollupMs` of counts, which the guide states |
97
+ | Concurrency | Ten replicas making mixed changes at once land in one linear history on every store: `tests/atomic-deployments.test.ts` |
98
+ | Load | `deployments.route-canary` and `deployments.bucket` in `surface-budget.json` |
99
+ | Tenant isolation | n/a: a deployment is an assistant's configuration, not a tenant's data. The runs it routes are operations, which are isolated: `tests/tenant-isolation.test.ts` |
100
+ | Security | [Review](./SECURITY.md#deployments): four findings fixed, two documented limitations |
101
+ | Upgrade | A 2.3 replica's deployment routes the same here, and every thread keeps its bucket: `tests/upgrade-previous-minor.test.ts` |
102
+ | Soak | 50,000 route, admit, and release cycles, 500 replica lifecycles, and 20,000 runs counted and judged from rollups, with no timer left running |
103
+
104
+ **The studio and its accounts** (`nexus-ai-pro-studio`):
105
+
106
+ | Requirement | Evidence |
107
+ | --- | --- |
108
+ | Conformance | Every view over its sources, with and without accounts: `studio/test/studio.test.ts`, `studio/test/team.test.ts`, `studio/test/deployments.test.ts` |
109
+ | Crash recovery | n/a: the studio keeps no state but its journal, which appends one line per entry and skips a line a crash cut short: `studio/test/security.test.ts` |
110
+ | Concurrency | n/a: every change goes through its source's own API, where races are settled: prompt and bundle labels by compare-and-set, deployments by `putIfVersion()` |
111
+ | Load | 500 signed-in reads within a budget relative to the machine: `studio/test/security.test.ts` |
112
+ | Tenant isolation | A studio over `tenantScope()` views lists one tenant's runs, and another tenant's trace is not found: `studio/test/security.test.ts` |
113
+ | Security | [Review](./SECURITY.md#the-studio-and-its-accounts): ten findings, all fixed; every route fuzzed by every role and with hostile input: `studio/test/security.test.ts` |
114
+ | Upgrade | The journal reads what 2.4 wrote, and accounts and configuration load unchanged: `studio/test/security.test.ts`, `studio/test/team.test.ts` |
115
+ | Soak | 2,000 sign-in, read, and change cycles with flat memory, and 200 servers started and closed with no handle left open: `studio/test/security.test.ts` |
116
+
117
+ **Still experimental**, each with what remains:
118
+ - **Images.** Recorded live conformance must pass on all three backends. The scheduled live workflow
119
+ records it wherever a backend's credential is set, and none has run with all three yet.
120
+ - **The Qdrant, Redis, Pinecone, Weaviate, and Chroma vector stores.** The contract must pass against
121
+ the real servers. The scheduled live workflow runs it against each one, Pinecone when its secret is
122
+ set, and its evidence is published when it has passed against all five.
123
+
124
+ A queued run's kind now names its revision, as `assistant:<id>@<revision>`. Code that reads the
125
+ server's runs by the `assistant:` prefix, as the server itself does, is unaffected.
126
+
127
+ A state store without `putIfVersion()` keeps its earlier behavior.
128
+
129
+ ## 2.4 stage (2.4.0)
130
+
131
+ Everything 2.4 adds is stable from the start and additive. These security fixes tighten behavior,
132
+ as the compatibility rules allow:
133
+ - the upload scanner checks the larger of the declared and actual sizes;
134
+ - an allowlist refuses a file with no MIME type;
135
+ - textual bytes are scanned;
136
+ - secret findings carry a preview instead of the value;
137
+ - card and phone matches must pass their checks.
138
+
139
+ New and stable:
140
+ - `confidence`, `minErrorRateIncrease`, `minFeedbackDrop`, and `resamples` on `watchCanaries()`;
141
+ the same options and `seed` on `compareRuns()`; `Regression.interval`;
142
+ - `Deployments.evaluate()` with `RunEvaluationOptions` and `RunEvaluationReport`;
143
+ - `RunRecord.feedback`, `RunManager.addFeedback()`, and `POST /runs/:id/feedback`;
144
+ - `nexus-ai-pro/adapter-kit`: the `define*()` builders, `Adapter`, `AdapterDefinition`,
145
+ `AdapterReport`, `AdapterError` and its codes, the contract runners, and the capability types.
146
+ Contract checks may be added in a minor release when they test something the contract already
147
+ promised. A new check for a new promise arrives behind a capability an adapter must declare.
148
+ - `nexus-ai-pro/protocols/ag-ui`, `nexus-ai-pro/protocols/a2a`, and `nexus-ai-pro/protocols/acp`:
149
+ the handlers, `a2aClient()`, `a2aTool()`, `serveAcp()`, and their types. Each speaks the
150
+ protocol version it names. A minor release may send an event or answer a method it did not
151
+ before, as a protocol adds them. An event or field already sent keeps its meaning. A new major
152
+ version of a protocol arrives beside the old one, not in its place.
153
+ - `nexus-ai-pro/runtime`, `runtimeInfo()`, `RuntimeInfo`, and `RuntimeName`, which may gain
154
+ names in a minor release; the `fetch` option on the OpenAI, Anthropic, Google, and Cohere
155
+ provider configurations.
156
+ - Portability, for the client, the kernel, the provider adapters, graphs, agents, and the agent
157
+ protocols: none of them starts needing Node.js in a minor release, and the build fails if one
158
+ does.
159
+
160
+ Without `confidence`, a canary is judged as before.
161
+
162
+ These security fixes tighten more behavior, each closing a finding of a graduation review in
163
+ [SECURITY.md](./SECURITY.md#threat-reviews):
164
+ - the Git loader never follows a symbolic link, nor a path that leaves the checkout;
165
+ - a gzipped sitemap may inflate to 50 MB at most, the sitemap protocol's maximum;
166
+ - a local MCP server inherits only what a process needs to run, not this process's environment.
167
+ `inheritEnv` restores the old behavior, by name or entirely;
168
+ - a canary is judged on runs, so each run counts once per feedback key, as the mean of its scores;
169
+ - the file prompt store's label compare-and-set holds within one process;
170
+ - changes to one deployment through one `Deployments` object apply in order.
171
+
172
+ ### Graduation
173
+
174
+ A surface left experimental status in 2.4 only when every requirement in
175
+ [How an item graduates](./ROADMAP.md#how-an-item-graduates) had evidence. That evidence is below.
176
+ "n/a" names a requirement that does not apply, and says why. Every test named here runs in CI.
177
+ Load and soak budgets are checked by `npm run bench:surfaces` and `npm run bench:runtime`, which are
178
+ part of `check:release`. Upgrade tests run against the published 2.3.0 package, installed as a
179
+ development alias.
180
+
181
+ Every graduated surface is covered by the 2.x compatibility rules, with no breaking change planned.
182
+ That is the "API stability" requirement, met by all of them.
183
+
184
+ **The SQLite adapters** (`nexus-ai-pro/sqlite` and its subpaths):
185
+
186
+ | Requirement | Evidence |
187
+ | --- | --- |
188
+ | Conformance | The operation store, store, and vector store contracts: `tests/sqlite.test.ts`, `tests/vector-stores.test.ts` |
189
+ | Crash recovery | A crash at every durable boundary resumes to the uninterrupted state: `tests/crash-injection.test.ts` |
190
+ | Concurrency | Ten workers race one thread, one idempotency key, one queue, and one budget: `tests/ten-workers.test.ts` |
191
+ | Load | `checkpoint.sqlite` and `operations.claim-10k-queued` in `runtime-budget.json`; `sqlite.vectors-query-2k` and `sqlite.store-put-get-search` in `surface-budget.json` |
192
+ | Tenant isolation | Every SQLite store: `tests/tenant-isolation.test.ts` |
193
+ | Security | [Review](./SECURITY.md#sqlite-adapters): no findings |
194
+ | Upgrade | A 2.3 file upgrades in place, and a 2.3 worker shares its queue: `tests/upgrade-previous-minor.test.ts`; likewise from 2.0: `tests/upgrade.test.ts` |
195
+ | Soak | 20,000 queue lifecycles and 2,000 open, migrate, and close cycles, with flat memory and no handle left open |
196
+
197
+ **The Postgres and SQLite vector stores** (`PostgresVectorStore`, `SqliteVectorStore`):
198
+
199
+ | Requirement | Evidence |
200
+ | --- | --- |
201
+ | Conformance | The vector store contract on pgvector and on SQLite: `tests/vector-stores.test.ts`. The retriever contract over each: `tests/graduation-conformance.test.ts` |
202
+ | Crash recovery | n/a: a store keeps no run state, and a reload upserts the same ids |
203
+ | Concurrency | Ten writers upserting the same ids at once leave one whole row per id: `tests/graduation-conformance.test.ts` |
204
+ | Load | `sqlite.vectors-query-2k` and `postgres.vectors-query-1k` in `surface-budget.json` |
205
+ | Tenant isolation | Both stores: `tests/tenant-isolation.test.ts` |
206
+ | Security | [Review](./SECURITY.md#the-postgres-and-sqlite-vector-stores): no findings |
207
+ | Upgrade | A table 2.3 wrote is searched and filtered here: `tests/upgrade-previous-minor.test.ts` |
208
+ | Soak | 1,000 write, search, and delete cycles on pgvector |
209
+
210
+ **The loaders** (`nexus-ai-pro/loaders/*`):
211
+
212
+ | Requirement | Evidence |
213
+ | --- | --- |
214
+ | Conformance | Every format, the web loader through the SSRF-safe fetch, and Git cloned and in place: `tests/loaders.test.ts` |
215
+ | Crash recovery | n/a: a loader keeps no state, and reloading replaces the same chunks |
216
+ | Concurrency | n/a: a loader shares no records |
217
+ | Load | `loaders.markdown-csv-html` in `surface-budget.json` |
218
+ | Tenant isolation | n/a: a loader stores nothing; the store it loads into is isolated |
219
+ | Security | [Review](./SECURITY.md#loaders): two findings, both fixed |
220
+ | Upgrade | The same files give the same ids and text as in 2.3: `tests/upgrade-previous-minor.test.ts` |
221
+ | Soak | 2,000 load cycles |
222
+
223
+ **The retrievers** (`nexus-ai-pro/rag/retrievers`):
224
+
225
+ | Requirement | Evidence |
226
+ | --- | --- |
227
+ | Conformance | The retriever contract on `KeywordIndex`, on a vector retriever over memory, SQLite, and pgvector, and on `hybridRetriever()`: `tests/graduation-conformance.test.ts` |
228
+ | Crash recovery | n/a: an index is held in memory, and rebuilt by loading |
229
+ | Concurrency | n/a: an index belongs to one process |
230
+ | Load | `retrievers.keyword-query-5k` and `retrievers.hybrid-query` in `surface-budget.json` |
231
+ | Tenant isolation | Filters narrow every retriever, by the contract; the stores behind them are isolated |
232
+ | Security | [Review](./SECURITY.md#retrievers): no findings |
233
+ | Upgrade | The same corpus ranks the same, score for score, as in 2.3: `tests/upgrade-previous-minor.test.ts` |
234
+ | Soak | 50,000 add and delete cycles |
235
+
236
+ **The MCP registry** (`nexus-ai-pro/mcp/registry`):
237
+
238
+ | Requirement | Evidence |
239
+ | --- | --- |
240
+ | Conformance | Servers over the protocol in process and as a real child process: `tests/mcp-registry.test.ts` |
241
+ | Crash recovery | A server that fails to start is reported, and the rest serve: `tests/mcp-registry.test.ts` |
242
+ | Concurrency | n/a: a registry shares no records |
243
+ | Load | `mcp.registry-tools-10-servers` in `surface-budget.json` |
244
+ | Tenant isolation | n/a: a registry stores nothing |
245
+ | Security | [Review](./SECURITY.md#mcp-registry): one finding, fixed |
246
+ | Upgrade | A configuration reads the same as in 2.3: `tests/upgrade-previous-minor.test.ts` |
247
+ | Soak | 1,000 connect, call, and close cycles, with no handle left open |
248
+
249
+ **The context hub** (`nexus-ai-pro/context-hub`):
250
+
251
+ | Requirement | Evidence |
252
+ | --- | --- |
253
+ | Conformance | The same behavior on memory, files, Redis, and Postgres: `tests/graduation-conformance.test.ts` |
254
+ | Crash recovery | A commit is content-addressed, so repeating an interrupted one writes the same version: `tests/context-hub.test.ts` |
255
+ | Concurrency | Two hubs racing for one label never both win, on every backend: `tests/graduation-conformance.test.ts` |
256
+ | Load | `context-hub.commit-resolve` in `surface-budget.json` |
257
+ | Tenant isolation | Context bundles: `tests/tenant-isolation.test.ts` |
258
+ | Security | [Review](./SECURITY.md#context-hub): one finding, fixed |
259
+ | Upgrade | A bundle has the same version as in 2.3, and a 2.3 export imports: `tests/upgrade-previous-minor.test.ts` |
260
+ | Soak | 2,000 commit, resolve, and render cycles |
261
+
262
+ **Insights** (`nexus-ai-pro/insights`):
263
+
264
+ | Requirement | Evidence |
265
+ | --- | --- |
266
+ | Conformance | The same issues from runs in memory and in Postgres: `tests/graduation-conformance.test.ts`; proposals in memory and in files: `tests/insights.test.ts` |
267
+ | Crash recovery | n/a: analysis is read-only, and a proposal is one write |
268
+ | Concurrency | n/a: a proposal is decided once, by a person |
269
+ | Load | `insights.find-issues-5k-runs` in `surface-budget.json` |
270
+ | Tenant isolation | Insights read through the trace store, which is isolated: `tests/tenant-isolation.test.ts` |
271
+ | Security | [Review](./SECURITY.md#insights): no findings |
272
+ | Upgrade | A 2.3 proposal reads here, and errors group under the same signatures: `tests/upgrade-previous-minor.test.ts` |
273
+ | Soak | 300 clustering cycles |
274
+
275
+ **Tenant limits and the server's worker queue** (`nexus-ai-pro/server/tenancy`, and the queue
276
+ `createAgentServer()` runs on its operation store):
277
+
278
+ | Requirement | Evidence |
279
+ | --- | --- |
280
+ | Conformance | Tenant usage in memory and in Redis; the queue on every operation store: `tests/deployments.test.ts`, `tests/operations.test.ts` |
281
+ | Crash recovery | A crash at every durable boundary resumes to the same state, and a draining worker hands a run to another: `tests/crash-injection.test.ts`, `tests/deployments.test.ts` |
282
+ | Concurrency | Ten workers drain one queue, and spend one tenant budget without over-granting a slot: `tests/ten-workers.test.ts` |
283
+ | Load | `tenancy.admit-release` in `surface-budget.json`; `operations.claim-10k-queued` and `server.sse-fanout` in `runtime-budget.json` |
284
+ | Tenant isolation | Operations: `tests/tenant-isolation.test.ts` |
285
+ | Security | [Review](./SECURITY.md#tenant-limits-and-the-worker-queue): no findings |
286
+ | Upgrade | A 2.3 worker and a 2.4 worker drain one queue: `tests/upgrade-previous-minor.test.ts` |
287
+ | Soak | 50,000 admit and release cycles, and 500 replica lifecycles with no timer left running |
288
+
289
+ **Still experimental**, each with what remains:
290
+ - **Deployments** (`nexus-ai-pro/server/deployments`). Two replicas changing one deployment in the
291
+ same instant can lose one change, because the state store has no atomic compare-and-set. Every
292
+ other requirement has evidence above or in its review.
293
+ - **Images.** Recorded live conformance must pass on all three backends. The scheduled live workflow
294
+ now records it, wherever a backend's credential is set.
295
+ - **The Qdrant, Redis, Pinecone, Weaviate, and Chroma vector stores.** The contract must pass against
296
+ the real servers, not only stubs. The scheduled live workflow now runs it against each one as a
297
+ service container, and Pinecone runs when its secret is set.
298
+ - **The studio and its accounts.** A threat review of its sign-in, sessions, and roles, and a soak
299
+ of its server, are still to do.
300
+
44
301
  ## 2.3 stage (2.3.0)
45
302
 
46
303
  Everything 2.3 adds is stable from the start and additive: no default changes meaning.
@@ -618,6 +875,9 @@ of the 1.x line.
618
875
 
619
876
  ## Deployment stage (1.24.0)
620
877
 
878
+ Tenant limits and the worker queue graduated in 2.4; see the 2.4 stage for their evidence.
879
+ Deployments remain experimental.
880
+
621
881
  Deployments (`nexus-ai-pro/server/deployments`), tenant limits (`nexus-ai-pro/server/tenancy`), and the
622
882
  server's worker queue are experimental in production readiness. Their contracts follow the 1.x rules.
623
883
 
@@ -632,6 +892,9 @@ server's worker queue are experimental in production readiness. Their contracts
632
892
 
633
893
  ## Team platform stage (1.23.0)
634
894
 
895
+ The context hub and insights graduated in 2.4; see the 2.4 stage for their evidence. The studio's
896
+ accounts remain experimental.
897
+
635
898
  The context hub (`nexus-ai-pro/context-hub`), insights (`nexus-ai-pro/insights`), and the studio's
636
899
  accounts are experimental in production readiness. Their contracts follow the 1.x rules.
637
900
 
@@ -644,6 +907,9 @@ accounts are experimental in production readiness. Their contracts follow the 1.
644
907
 
645
908
  ## Retrieval breadth stage (1.22.0)
646
909
 
910
+ The loaders, the SQLite vector store, the retrievers, and the MCP registry graduated in 2.4; see the
911
+ 2.4 stage for their evidence. The Redis, Pinecone, Weaviate, and Chroma stores remain experimental.
912
+
647
913
  The loaders (`nexus-ai-pro/loaders/*`), the Redis, Pinecone, Weaviate, Chroma, and SQLite vector
648
914
  stores, the retrievers (`nexus-ai-pro/rag/retrievers`), and the MCP registry
649
915
  (`nexus-ai-pro/mcp/registry`) are experimental in production readiness. Their contracts follow the
@@ -660,6 +926,8 @@ stores, the retrievers (`nexus-ai-pro/rag/retrievers`), and the MCP registry
660
926
 
661
927
  ## Durable execution stage (1.21.0)
662
928
 
929
+ The SQLite adapters graduated in 2.4; see the 2.4 stage for their evidence.
930
+
663
931
  Functional workflows (`nexus-ai-pro/graph/functional`) and the SQLite adapters (`nexus-ai-pro/sqlite`)
664
932
  are experimental in production readiness. Their contracts follow the 1.x rules.
665
933
 
@@ -672,6 +940,9 @@ are experimental in production readiness. Their contracts follow the 1.x rules.
672
940
 
673
941
  ## Retrieval stores stage (1.20.0)
674
942
 
943
+ `PostgresVectorStore` graduated in 2.4; see the 2.4 stage for its evidence. `QdrantVectorStore`
944
+ remains experimental.
945
+
675
946
  `PostgresVectorStore` (`nexus-ai-pro/postgres/vectors`) and `QdrantVectorStore` (`nexus-ai-pro/rag/qdrant`)
676
947
  are experimental in production readiness. The `VectorStore` contract they share with
677
948
  `MemoryVectorStore` follows the 1.x rules: a minor release may add optional methods and options, not