@jterrats/open-orchestra 1.0.16 → 1.0.18

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 (313) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/CLAUDE.md +25 -2
  3. package/README.md +32 -9
  4. package/dist/active-runtime-store.d.ts +18 -0
  5. package/dist/active-runtime-store.js +75 -0
  6. package/dist/active-runtime-store.js.map +1 -0
  7. package/dist/benchmark.js +65 -27
  8. package/dist/benchmark.js.map +1 -1
  9. package/dist/chat-api-errors.d.ts +7 -0
  10. package/dist/chat-api-errors.js +15 -0
  11. package/dist/chat-api-errors.js.map +1 -0
  12. package/dist/chat-api-message-persistence.d.ts +12 -0
  13. package/dist/chat-api-message-persistence.js +125 -0
  14. package/dist/chat-api-message-persistence.js.map +1 -0
  15. package/dist/chat-api-records.d.ts +35 -0
  16. package/dist/chat-api-records.js +94 -0
  17. package/dist/chat-api-records.js.map +1 -0
  18. package/dist/chat-api-service.d.ts +32 -0
  19. package/dist/chat-api-service.js +120 -0
  20. package/dist/chat-api-service.js.map +1 -0
  21. package/dist/chat-api-storage.d.ts +1 -0
  22. package/dist/chat-api-storage.js +14 -0
  23. package/dist/chat-api-storage.js.map +1 -0
  24. package/dist/chat-api-types.d.ts +81 -0
  25. package/dist/chat-api-types.js +2 -0
  26. package/dist/chat-api-types.js.map +1 -0
  27. package/dist/chat-compliance-service.d.ts +60 -0
  28. package/dist/chat-compliance-service.js +241 -0
  29. package/dist/chat-compliance-service.js.map +1 -0
  30. package/dist/chat-event-stream.d.ts +13 -0
  31. package/dist/chat-event-stream.js +124 -0
  32. package/dist/chat-event-stream.js.map +1 -0
  33. package/dist/chat-pagination.d.ts +6 -0
  34. package/dist/chat-pagination.js +64 -0
  35. package/dist/chat-pagination.js.map +1 -0
  36. package/dist/chat-storage-actor-validation.d.ts +4 -0
  37. package/dist/chat-storage-actor-validation.js +65 -0
  38. package/dist/chat-storage-actor-validation.js.map +1 -0
  39. package/dist/chat-storage-content-policy.d.ts +6 -0
  40. package/dist/chat-storage-content-policy.js +84 -0
  41. package/dist/chat-storage-content-policy.js.map +1 -0
  42. package/dist/chat-storage-errors.d.ts +20 -0
  43. package/dist/chat-storage-errors.js +17 -0
  44. package/dist/chat-storage-errors.js.map +1 -0
  45. package/dist/chat-storage-local-files.d.ts +17 -0
  46. package/dist/chat-storage-local-files.js +78 -0
  47. package/dist/chat-storage-local-files.js.map +1 -0
  48. package/dist/chat-storage-local-paths.d.ts +6 -0
  49. package/dist/chat-storage-local-paths.js +124 -0
  50. package/dist/chat-storage-local-paths.js.map +1 -0
  51. package/dist/chat-storage-local-projection.d.ts +10 -0
  52. package/dist/chat-storage-local-projection.js +55 -0
  53. package/dist/chat-storage-local-projection.js.map +1 -0
  54. package/dist/chat-storage-local-records.d.ts +13 -0
  55. package/dist/chat-storage-local-records.js +56 -0
  56. package/dist/chat-storage-local-records.js.map +1 -0
  57. package/dist/chat-storage-local.d.ts +6 -0
  58. package/dist/chat-storage-local.js +114 -0
  59. package/dist/chat-storage-local.js.map +1 -0
  60. package/dist/chat-storage-validation.d.ts +10 -0
  61. package/dist/chat-storage-validation.js +100 -0
  62. package/dist/chat-storage-validation.js.map +1 -0
  63. package/dist/chat-storage.d.ts +16 -0
  64. package/dist/chat-storage.js +4 -0
  65. package/dist/chat-storage.js.map +1 -0
  66. package/dist/chat-workflow-timeline.d.ts +17 -0
  67. package/dist/chat-workflow-timeline.js +210 -0
  68. package/dist/chat-workflow-timeline.js.map +1 -0
  69. package/dist/{workspace-claude-settings.d.ts → claude-settings.d.ts} +22 -3
  70. package/dist/{workspace-claude-settings.js → claude-settings.js} +28 -9
  71. package/dist/claude-settings.js.map +1 -0
  72. package/dist/command-init.d.ts +2 -0
  73. package/dist/command-init.js +150 -0
  74. package/dist/command-init.js.map +1 -0
  75. package/dist/command-manifest.js +1 -1
  76. package/dist/command-manifest.js.map +1 -1
  77. package/dist/commands.d.ts +1 -1
  78. package/dist/commands.js +1 -140
  79. package/dist/commands.js.map +1 -1
  80. package/dist/constants.d.ts +1 -0
  81. package/dist/constants.js +1 -0
  82. package/dist/constants.js.map +1 -1
  83. package/dist/context-runtime-preprocessor.d.ts +41 -0
  84. package/dist/context-runtime-preprocessor.js +199 -0
  85. package/dist/context-runtime-preprocessor.js.map +1 -0
  86. package/dist/cursor-settings.d.ts +25 -0
  87. package/dist/cursor-settings.js +72 -0
  88. package/dist/cursor-settings.js.map +1 -0
  89. package/dist/health-commands.js +43 -3
  90. package/dist/health-commands.js.map +1 -1
  91. package/dist/metrics-commands.js +3 -0
  92. package/dist/metrics-commands.js.map +1 -1
  93. package/dist/model-aliases.d.ts +5 -0
  94. package/dist/model-aliases.js +37 -0
  95. package/dist/model-aliases.js.map +1 -0
  96. package/dist/ollama-provider.js +25 -0
  97. package/dist/ollama-provider.js.map +1 -1
  98. package/dist/phase-playbooks.js +11 -0
  99. package/dist/phase-playbooks.js.map +1 -1
  100. package/dist/provider-agent-wrapper.js +14 -0
  101. package/dist/provider-agent-wrapper.js.map +1 -1
  102. package/dist/runtime-adapters.js +56 -0
  103. package/dist/runtime-adapters.js.map +1 -1
  104. package/dist/runtime-bootstrap.js +34 -11
  105. package/dist/runtime-bootstrap.js.map +1 -1
  106. package/dist/runtime-capacity-policy.d.ts +38 -0
  107. package/dist/runtime-capacity-policy.js +117 -0
  108. package/dist/runtime-capacity-policy.js.map +1 -0
  109. package/dist/runtime-capacity-scheduler-helpers.d.ts +40 -0
  110. package/dist/runtime-capacity-scheduler-helpers.js +111 -0
  111. package/dist/runtime-capacity-scheduler-helpers.js.map +1 -0
  112. package/dist/runtime-capacity-scheduler-state.d.ts +44 -0
  113. package/dist/runtime-capacity-scheduler-state.js +128 -0
  114. package/dist/runtime-capacity-scheduler-state.js.map +1 -0
  115. package/dist/runtime-capacity-scheduler.d.ts +34 -0
  116. package/dist/runtime-capacity-scheduler.js +193 -0
  117. package/dist/runtime-capacity-scheduler.js.map +1 -0
  118. package/dist/runtime-capacity-snapshot.d.ts +14 -0
  119. package/dist/runtime-capacity-snapshot.js +87 -0
  120. package/dist/runtime-capacity-snapshot.js.map +1 -0
  121. package/dist/runtime-child-prompt.d.ts +2 -1
  122. package/dist/runtime-child-prompt.js +12 -1
  123. package/dist/runtime-child-prompt.js.map +1 -1
  124. package/dist/runtime-claude-native-bridge.js +2 -1
  125. package/dist/runtime-claude-native-bridge.js.map +1 -1
  126. package/dist/runtime-commands.js +6 -0
  127. package/dist/runtime-commands.js.map +1 -1
  128. package/dist/runtime-context-manifest.d.ts +4 -1
  129. package/dist/runtime-context-manifest.js +59 -3
  130. package/dist/runtime-context-manifest.js.map +1 -1
  131. package/dist/runtime-execution-adapters.js +19 -0
  132. package/dist/runtime-execution-adapters.js.map +1 -1
  133. package/dist/runtime-execution-renderer.js +4 -0
  134. package/dist/runtime-execution-renderer.js.map +1 -1
  135. package/dist/runtime-execution.js +13 -82
  136. package/dist/runtime-execution.js.map +1 -1
  137. package/dist/runtime-hooks.d.ts +46 -0
  138. package/dist/runtime-hooks.js +95 -0
  139. package/dist/runtime-hooks.js.map +1 -0
  140. package/dist/runtime-lifecycle-watch.d.ts +5 -2
  141. package/dist/runtime-lifecycle-watch.js +19 -3
  142. package/dist/runtime-lifecycle-watch.js.map +1 -1
  143. package/dist/runtime-load-balancer.d.ts +12 -0
  144. package/dist/runtime-load-balancer.js +106 -0
  145. package/dist/runtime-load-balancer.js.map +1 -0
  146. package/dist/runtime-parent-actions.js +5 -0
  147. package/dist/runtime-parent-actions.js.map +1 -1
  148. package/dist/runtime-spawn-bridge.js +24 -0
  149. package/dist/runtime-spawn-bridge.js.map +1 -1
  150. package/dist/runtime-spawn-guidance.js +15 -46
  151. package/dist/runtime-spawn-guidance.js.map +1 -1
  152. package/dist/runtime-worker-registry.d.ts +19 -0
  153. package/dist/runtime-worker-registry.js +84 -0
  154. package/dist/runtime-worker-registry.js.map +1 -0
  155. package/dist/security/chat-guardrail-policy.d.ts +7 -0
  156. package/dist/security/chat-guardrail-policy.js +61 -0
  157. package/dist/security/chat-guardrail-policy.js.map +1 -0
  158. package/dist/security/chat-guardrail-types.d.ts +65 -0
  159. package/dist/security/chat-guardrail-types.js +2 -0
  160. package/dist/security/chat-guardrail-types.js.map +1 -0
  161. package/dist/security/chat-guardrail-validation.d.ts +9 -0
  162. package/dist/security/chat-guardrail-validation.js +64 -0
  163. package/dist/security/chat-guardrail-validation.js.map +1 -0
  164. package/dist/security/chat-guardrails.d.ts +3 -0
  165. package/dist/security/chat-guardrails.js +136 -0
  166. package/dist/security/chat-guardrails.js.map +1 -0
  167. package/dist/security/content-classifier.d.ts +2 -0
  168. package/dist/security/content-classifier.js +179 -0
  169. package/dist/security/content-classifier.js.map +1 -0
  170. package/dist/security/operation-contract-types.d.ts +28 -0
  171. package/dist/security/operation-contract-types.js +2 -0
  172. package/dist/security/operation-contract-types.js.map +1 -0
  173. package/dist/security/operation-contract.d.ts +2 -0
  174. package/dist/security/operation-contract.js +169 -0
  175. package/dist/security/operation-contract.js.map +1 -0
  176. package/dist/security/payment-card-detection.d.ts +3 -0
  177. package/dist/security/payment-card-detection.js +48 -0
  178. package/dist/security/payment-card-detection.js.map +1 -0
  179. package/dist/security/policy-engine.d.ts +2 -0
  180. package/dist/security/policy-engine.js +142 -0
  181. package/dist/security/policy-engine.js.map +1 -0
  182. package/dist/security/policy-types.d.ts +79 -0
  183. package/dist/security/policy-types.js +7 -0
  184. package/dist/security/policy-types.js.map +1 -0
  185. package/dist/security/prompt-intake.d.ts +13 -0
  186. package/dist/security/prompt-intake.js +33 -0
  187. package/dist/security/prompt-intake.js.map +1 -0
  188. package/dist/security/provider-egress-policy.d.ts +27 -0
  189. package/dist/security/provider-egress-policy.js +72 -0
  190. package/dist/security/provider-egress-policy.js.map +1 -0
  191. package/dist/security/public-api-auth.d.ts +20 -0
  192. package/dist/security/public-api-auth.js +55 -0
  193. package/dist/security/public-api-auth.js.map +1 -0
  194. package/dist/security/public-api-policy.d.ts +8 -0
  195. package/dist/security/public-api-policy.js +40 -0
  196. package/dist/security/public-api-policy.js.map +1 -0
  197. package/dist/security/redaction.d.ts +3 -0
  198. package/dist/security/redaction.js +95 -0
  199. package/dist/security/redaction.js.map +1 -0
  200. package/dist/security/restricted-content-quarantine.d.ts +17 -0
  201. package/dist/security/restricted-content-quarantine.js +50 -0
  202. package/dist/security/restricted-content-quarantine.js.map +1 -0
  203. package/dist/security/restricted-data-classifier.d.ts +9 -0
  204. package/dist/security/restricted-data-classifier.js +254 -0
  205. package/dist/security/restricted-data-classifier.js.map +1 -0
  206. package/dist/security/sink-encoding.d.ts +6 -0
  207. package/dist/security/sink-encoding.js +40 -0
  208. package/dist/security/sink-encoding.js.map +1 -0
  209. package/dist/skills-render.js +7 -14
  210. package/dist/skills-render.js.map +1 -1
  211. package/dist/sprint-commands.js +33 -22
  212. package/dist/sprint-commands.js.map +1 -1
  213. package/dist/telemetry-redaction.d.ts +2 -0
  214. package/dist/telemetry-redaction.js +25 -2
  215. package/dist/telemetry-redaction.js.map +1 -1
  216. package/dist/transcription-failures.d.ts +2 -0
  217. package/dist/transcription-failures.js +4 -0
  218. package/dist/transcription-failures.js.map +1 -0
  219. package/dist/transcription-media-preflight.d.ts +9 -0
  220. package/dist/transcription-media-preflight.js +147 -0
  221. package/dist/transcription-media-preflight.js.map +1 -0
  222. package/dist/transcription-request.d.ts +13 -0
  223. package/dist/transcription-request.js +150 -0
  224. package/dist/transcription-request.js.map +1 -0
  225. package/dist/transcription-source-policy.d.ts +4 -0
  226. package/dist/transcription-source-policy.js +43 -0
  227. package/dist/transcription-source-policy.js.map +1 -0
  228. package/dist/transcription-types.d.ts +161 -0
  229. package/dist/transcription-types.js +2 -0
  230. package/dist/transcription-types.js.map +1 -0
  231. package/dist/types/chat.d.ts +203 -0
  232. package/dist/types/chat.js +10 -0
  233. package/dist/types/chat.js.map +1 -0
  234. package/dist/types/model-config.d.ts +4 -0
  235. package/dist/types/public-api.d.ts +75 -0
  236. package/dist/types/public-api.js +2 -0
  237. package/dist/types/public-api.js.map +1 -0
  238. package/dist/types/restricted-data.d.ts +69 -0
  239. package/dist/types/restricted-data.js +8 -0
  240. package/dist/types/restricted-data.js.map +1 -0
  241. package/dist/types/restricted-fragment.d.ts +82 -0
  242. package/dist/types/restricted-fragment.js +14 -0
  243. package/dist/types/restricted-fragment.js.map +1 -0
  244. package/dist/types/runtime.d.ts +159 -0
  245. package/dist/types.d.ts +9 -1
  246. package/dist/types.js +1 -0
  247. package/dist/types.js.map +1 -1
  248. package/dist/web-api.js +24 -0
  249. package/dist/web-api.js.map +1 -1
  250. package/dist/web-artifact-parsers.d.ts +6 -0
  251. package/dist/web-artifact-parsers.js +244 -0
  252. package/dist/web-artifact-parsers.js.map +1 -0
  253. package/dist/web-artifact-types.d.ts +76 -0
  254. package/dist/web-artifact-types.js +2 -0
  255. package/dist/web-artifact-types.js.map +1 -0
  256. package/dist/web-artifacts.d.ts +2 -43
  257. package/dist/web-artifacts.js +73 -58
  258. package/dist/web-artifacts.js.map +1 -1
  259. package/dist/web-chat-route-inputs.d.ts +11 -0
  260. package/dist/web-chat-route-inputs.js +156 -0
  261. package/dist/web-chat-route-inputs.js.map +1 -0
  262. package/dist/web-chat-routes.d.ts +7 -0
  263. package/dist/web-chat-routes.js +213 -0
  264. package/dist/web-chat-routes.js.map +1 -0
  265. package/dist/web-console/assets/index-CJup1cIA.css +1 -0
  266. package/dist/web-console/assets/index-CVDOfipu.js +11 -0
  267. package/dist/web-console/index.html +2 -2
  268. package/dist/web-evidence.d.ts +1 -1
  269. package/dist/web-evidence.js +9 -2
  270. package/dist/web-evidence.js.map +1 -1
  271. package/dist/web-public-route-inputs.d.ts +14 -0
  272. package/dist/web-public-route-inputs.js +136 -0
  273. package/dist/web-public-route-inputs.js.map +1 -0
  274. package/dist/web-public-routes.d.ts +6 -0
  275. package/dist/web-public-routes.js +194 -0
  276. package/dist/web-public-routes.js.map +1 -0
  277. package/dist/web-public-service.d.ts +16 -0
  278. package/dist/web-public-service.js +154 -0
  279. package/dist/web-public-service.js.map +1 -0
  280. package/dist/workflow-phase-planner.js +5 -3
  281. package/dist/workflow-phase-planner.js.map +1 -1
  282. package/dist/workflow-phases.js +5 -0
  283. package/dist/workflow-phases.js.map +1 -1
  284. package/dist/workflow-run-commands.js +89 -10
  285. package/dist/workflow-run-commands.js.map +1 -1
  286. package/dist/workflow-services.js +5 -0
  287. package/dist/workflow-services.js.map +1 -1
  288. package/dist/workspace-runtime-bootstrap.js +15 -4
  289. package/dist/workspace-runtime-bootstrap.js.map +1 -1
  290. package/docs/audio-video-transcription-skill.md +102 -70
  291. package/docs/chat-audit-retention.md +76 -0
  292. package/docs/chat-provider-provenance-ledger.md +75 -0
  293. package/docs/context-runtime-preprocessing.md +37 -0
  294. package/docs/orchestra-mvp.md +8 -2
  295. package/docs/public-api-contract.md +43 -0
  296. package/docs/release-test-matrix.md +14 -14
  297. package/docs/restricted-fragment-storage-contract.md +147 -0
  298. package/docs/runtime-adapters.md +47 -7
  299. package/docs/runtime-capacity.md +57 -0
  300. package/docs/security-saas-orchestrator.md +368 -0
  301. package/docs/site-manifest.json +128 -30
  302. package/package.json +5 -2
  303. package/site/dist/_headers +9 -0
  304. package/site/dist/_redirects +2 -0
  305. package/site/dist/architecture.mmd +61 -0
  306. package/site/dist/assets/index-Bi8l6tCE.js +10 -0
  307. package/site/dist/assets/index-BsCLqY__.css +1 -0
  308. package/site/dist/favicon.svg +19 -0
  309. package/site/dist/index.html +28 -0
  310. package/site/package.json +19 -0
  311. package/dist/web-console/assets/index-BHs7OIv8.css +0 -1
  312. package/dist/web-console/assets/index-BJuVTqfQ.js +0 -11
  313. package/dist/workspace-claude-settings.js.map +0 -1
@@ -0,0 +1,76 @@
1
+ # Chat Audit, Retention, and Export
2
+
3
+ `GH-498-CHAT-AUDIT-RETENTION` defines the compliance layer for workspace chat records.
4
+
5
+ ## Defaults
6
+
7
+ - Local chat storage persists under `.agent-workflow/chat/v1`.
8
+ - New threads and messages default to `redacted_only` retention and export policy.
9
+ - Logical delete uses tombstones instead of physical removal so evidence actions remain auditable.
10
+ - Export defaults to redacted output.
11
+
12
+ ## Export Scope
13
+
14
+ The compliance/export layer supports three evidence scopes inside a tenant/workspace:
15
+
16
+ - `thread`
17
+ - `task`
18
+ - `run`
19
+
20
+ Exports produce:
21
+
22
+ - JSON records suitable for machine processing and evidence attachment
23
+ - Markdown suitable for human review and release evidence
24
+
25
+ For local mode, exports are redacted-only. Even if future retention policies allow raw storage, export policy must explicitly allow raw export before any non-redacted content can leave the store.
26
+
27
+ Restricted-data detections are export-safe only when represented as sanitized
28
+ metadata. Export JSON and Markdown may include category, rule id, occurrence
29
+ count, redaction marker, decision id, source message id, provider-egress
30
+ decision, and raw-persistence decision. They must not include raw passwords,
31
+ tokens, private keys, payment data, sensitive PII, request bodies, prompt
32
+ samples, ciphertext blobs, wrapped keys, or KMS/vault internals.
33
+
34
+ If an export encounters restricted values in legacy or future raw-allowed
35
+ records, the export copy is reclassified and redacted before rendering. The
36
+ stored record is not mutated by export, and the export audit event records only
37
+ the sanitized restricted event summary.
38
+
39
+ ## Delete Behavior
40
+
41
+ - Delete is logical, not physical.
42
+ - Tombstoned threads and messages keep audit metadata.
43
+ - Tombstoned content is not raw exportable.
44
+ - Workspace isolation remains enforced by the chat storage path model and scope filtering.
45
+
46
+ ## Audit Trail
47
+
48
+ Sensitive lifecycle actions append workflow events:
49
+
50
+ - `CHAT_EXPORT_RECORDED`
51
+ - `CHAT_DELETE_RECORDED`
52
+ - restricted detections/blocks as sanitized restricted-data audit summaries
53
+
54
+ Audit metadata should include:
55
+
56
+ - requesting actor id and role
57
+ - tenant and workspace
58
+ - selected scope kind (`thread`, `task`, `run`)
59
+ - affected task/run/thread identifiers
60
+ - timestamps
61
+ - affected thread/message counts
62
+ - restricted event count and sanitized category/count/marker summaries when
63
+ restricted values are detected or blocked
64
+
65
+ ## SaaS vs Local
66
+
67
+ Local mode uses workspace-local files and workflow events as the audit ledger.
68
+
69
+ SaaS mode will need stronger policy inputs:
70
+
71
+ - tenant-configured retention classes
72
+ - export authorization policy
73
+ - delete/legal-hold policy
74
+ - centralized audit retention and access control
75
+
76
+ This story keeps the contract and local behavior explicit so the SaaS implementation can reuse the same policy concepts without changing the chat domain model.
@@ -0,0 +1,75 @@
1
+ # Chat Provider Provenance Ledger
2
+
3
+ ## Purpose
4
+
5
+ Chat provider provenance records who initiated model-backed work, where it
6
+ belongs, which provider/model executed it, and the usage/cost metadata returned
7
+ by the provider or runtime. The ledger supports SaaS tenant reporting, local
8
+ debugging, budget gates, and audit review without exposing raw prompts or
9
+ provider secrets.
10
+
11
+ ## Dimensions
12
+
13
+ Each model provenance record is scoped by:
14
+
15
+ - `tenantId`, `workspaceId`, `task`, `runId`, `phase`, and `sessionId` when
16
+ available.
17
+ - `role`, `actor`, and `initiatedBy` to distinguish human, parent agent,
18
+ subagent, and system initiated requests.
19
+ - `provider`, `model`, `requestId`, `responseId`, `promptId`, and
20
+ `finishReason`.
21
+ - `inputTokens`, `outputTokens`, `estimatedCostUsd`, `usageSource`, and
22
+ `costSource`.
23
+
24
+ Missing tenant/workspace metadata falls back to local aggregate buckets so
25
+ existing local workflows remain compatible while SaaS calls can provide full
26
+ scope.
27
+
28
+ ## Chat Message Contract
29
+
30
+ Chat messages may carry provider metadata in `provenance` when the message is
31
+ created from model output:
32
+
33
+ - `provider`, `model`, `requestId`, and `responseId` identify the execution.
34
+ - `inputTokens`, `outputTokens`, and `estimatedCostUsd` provide reporting
35
+ context.
36
+ - `usageSource` and `costSource` indicate whether values came from the provider,
37
+ runtime, an estimate, or are unavailable.
38
+
39
+ Persisted chat content remains governed by the existing redaction, retention,
40
+ export, and delete policies. Provenance metadata must not contain raw prompts,
41
+ secrets, authorization headers, provider base URLs, or unredacted sensitive
42
+ payloads.
43
+
44
+ ## Budget And Policy Gates
45
+
46
+ Budget checks read model provenance events and aggregate by total, role,
47
+ provider, tenant, workspace, actor, initiator, and phase. Provider execution
48
+ should run preflight budget and egress policy checks before model calls. Blocks
49
+ and warnings should record safe metadata only.
50
+
51
+ ## Reporting Defaults
52
+
53
+ Local usage reports include:
54
+
55
+ - `totals`
56
+ - `byRole`
57
+ - `byProvider`
58
+ - `byTenant`
59
+ - `byWorkspace`
60
+ - `byActor`
61
+ - `byInitiator`
62
+ - `byPhase`
63
+
64
+ SaaS reporting can use the same shape for tenant/workspace dashboards. Cost
65
+ values are estimates unless `costSource` is provider-backed pricing data.
66
+
67
+ ## Follow-Up Work
68
+
69
+ - Wire public/chat API model responses through provider-backed execution once
70
+ response generation is in scope.
71
+ - Add UI reporting for tenant/workspace usage when SaaS dashboards are ready.
72
+ - Align export/delete behavior with GH-498 so evidence exports include safe
73
+ ledger metadata only.
74
+ - Apply GH-507 restricted-data decisions before any raw sensitive data can be
75
+ retained or sent to providers.
@@ -0,0 +1,37 @@
1
+ # Runtime Context Preprocessing
2
+
3
+ Runtime subagent delegation builds a bounded preprocessed context bundle before
4
+ rendering spawn prompts. The bundle is embedded in the runtime context manifest
5
+ and is the default context a child runtime should use.
6
+
7
+ ## Reduction Contract
8
+
9
+ Each file record includes:
10
+
11
+ - `sourcePath`: workspace-relative source path.
12
+ - `strategy`: `passthrough`, `schema-extraction`, `section-extraction`,
13
+ `head-tail-truncation`, or `missing`.
14
+ - `originalSize`: original line and byte count.
15
+ - `finalSize`: reduced line and byte count.
16
+ - `omittedContentWarning`: explicit warning when content was reduced or missing.
17
+
18
+ Delegates may cite full source paths from the bundle, but should avoid loading
19
+ raw files unless the reduced context is insufficient for the assigned work.
20
+
21
+ ## Deterministic Strategies
22
+
23
+ - Small files pass through unchanged.
24
+ - TypeScript files prefer exported schema and contract declarations.
25
+ - Markdown files prefer relevant sections based on task, role, phase, and
26
+ delegated ownership paths.
27
+ - Other large files fall back to annotated head/tail truncation.
28
+
29
+ ## Configuration
30
+
31
+ Runtime preprocessing defaults are line-based and can be configured with:
32
+
33
+ - `OPEN_ORCHESTRA_RUNTIME_CONTEXT_MAX_LINES_PER_FILE`
34
+ - `OPEN_ORCHESTRA_RUNTIME_CONTEXT_TOTAL_LINE_BUDGET`
35
+
36
+ The runtime context pack remains available as supplemental search evidence. The
37
+ preprocessed bundle is the prompt-local default.
@@ -46,7 +46,6 @@ updates still replace only that block.
46
46
 
47
47
  Open Orchestra should treat skills as demand-loaded capabilities. Main files such as `AGENTS.md`, `CLAUDE.md`, Cursor rules, and `ORCHESTRA.md` should contain a compact index and activation rules, while detailed procedures live in skill files. See [skill-loading-strategy.md](skill-loading-strategy.md).
48
48
 
49
-
50
49
  ## Commands
51
50
 
52
51
  Use the installed CLI form in project documentation and automation:
@@ -270,11 +269,18 @@ Release go/no-go:
270
269
  - Confirm `orchestra release check --json` passes the package provenance gate,
271
270
  which runs `npm pack --dry-run --json` and rejects private workflow state,
272
271
  generated prompts, env files, and missing public package entry points.
272
+ - Confirm `npm run package:validate` passes before publishing. This rebuilds the
273
+ package dry-run file list without lifecycle scripts and verifies the CLI bin,
274
+ compiled dist output, legacy and React web console assets, built site assets,
275
+ docs, rules, skills, package metadata, README, and changelog are included.
273
276
  - Confirm GitHub Actions CI is green for the latest pushed HEAD.
274
277
  - Confirm installed-package dogfooding passes on `ubuntu-latest`,
275
278
  `macos-latest`, and `windows-latest`.
276
279
  - Confirm `Create release tag`, site publish, and npm publish workflows are
277
280
  successful for the intended release commit.
281
+ - After publish, confirm the registry exposes the exact version from
282
+ `package.json` with
283
+ `npm view @jterrats/open-orchestra@$(node -p "require('./package.json').version") version`.
278
284
  - Confirm the npm publish workflow authenticates with either a maintainer
279
285
  `NPM_TOKEN` that has read-write access plus CI 2FA bypass for
280
286
  `@jterrats/open-orchestra`, or npm Trusted Publishing/OIDC configured with
@@ -405,7 +411,6 @@ orchestra workflow clarify-list --run <run-id>
405
411
  runs/
406
412
  ```
407
413
 
408
-
409
414
  ## Stable JSON Contracts
410
415
 
411
416
  The VS Code Control Center should consume stable JSON outputs instead of parsing human-readable text or duplicating file reads. Current UI-facing commands include:
@@ -496,6 +501,7 @@ The VS Code Control Center scaffold is under `extensions/vscode-open-orchestra`.
496
501
  `orchestra estimate` declares the three-mode effort baseline at story start. After the autonomous run completes, `orchestra benchmark` joins the declared estimate with the actual cycle time and quality signals automatically computed from the event log.
497
502
 
498
503
  Quality signals collected automatically:
504
+
499
505
  - `REVIEW_RECORDED` events → review count, blocking reviews (result=block or severity high/critical)
500
506
  - `EVIDENCE_ADDED` events → evidence artifact count
501
507
  - `LESSON_RECORDED` events → lesson count
@@ -0,0 +1,43 @@
1
+ # Public API Contract
2
+
3
+ The public `/api/v1` surface is owned by Open Orchestra. It exposes Orchestra
4
+ DTOs and request semantics only; it must not expose provider ids, raw vendor
5
+ payloads, provider credentials, or backend base URLs.
6
+
7
+ ## Workspace And Principal Isolation
8
+
9
+ - Public API data must be isolated by project workspace.
10
+ - Public API data must also be bound to a principal so threads and messages from
11
+ one user are not listed or read by another user in the same project.
12
+ - The current `/api/v1` slice uses an explicit local-development auth adapter
13
+ that reads `x-orchestra-user-id` and optional `x-orchestra-user-name` headers.
14
+ This is not a production IAM mechanism; production deployments must replace
15
+ the adapter with session/API-key authentication before public exposure.
16
+ - Routes pass a server-bound auth context into services. Tenant, workspace,
17
+ task, run, phase, session, actor, provider, model, and backend URL values from
18
+ the request body or query are rejected and are never authoritative.
19
+ - Storage scope is computed server-side from the workspace root plus principal,
20
+ so users in the same workspace cannot list, read, or write each other's public
21
+ threads through `/api/v1`.
22
+
23
+ ## Bounds, Rate Limits, And Idempotency
24
+
25
+ - Public JSON request bodies are bounded to 64 KiB.
26
+ - Public string fields and headers are bounded before execution: thread titles,
27
+ message text, request ids, thread ids, cursors, idempotency keys, local-dev
28
+ principal ids, and display names all have explicit maximum lengths.
29
+ - Side-effecting message writes require `Idempotency-Key`. Thread creation may
30
+ use `Idempotency-Key`; replays are scoped by workspace and authenticated
31
+ principal, and conflicts return the stable `idempotency_conflict` error code.
32
+ - `/api/v1` currently enforces process-local per-principal rate limiting and
33
+ concurrent request admission. Durable, shared rate-limit and idempotency
34
+ storage is still required before a multi-process or public production rollout.
35
+ - Rate limited requests return `rate_limited` with HTTP 429 and a sanitized
36
+ message.
37
+
38
+ ## Transport Security
39
+
40
+ - Public deployments must terminate TLS 1.2+ at the Open Orchestra boundary.
41
+ - Plain HTTP is acceptable only for local development on loopback interfaces.
42
+ - Provider traffic, secrets, and backend topology remain internal and must not
43
+ be exposed through public API responses.
@@ -65,20 +65,20 @@ GitHub Actions secret.
65
65
 
66
66
  ## Required Flows
67
67
 
68
- | Flow | Command | Evidence |
69
- | ---------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
- | Source quality gate | `npm run precommit` | lint, typecheck, secret scan, security audit, build, unit tests, workflow validation |
71
- | Secret scanning gate | `npm run secret-scan` | Gitleaks scan with `.gitleaks.toml` when the binary is installed; lightweight fallback for offline local development |
72
- | Duplicate-code gate | `npm run duplicates` | jscpd duplicate-code report with generated/runtime outputs excluded and collection-standards follow-up for duplicated domain lists |
73
- | Task split guard | `node --test test/task-split-assessment.test.js` | PO/BA functional oversize, Architect technical complexity, routine small-task non-blocking behavior, and markdown evidence rendering |
74
- | Sonar quality gate | GitHub Actions: `Sonar` or local SonarQube import | conditional quality gate for duplication, bugs, code smells, maintainability, coverage readiness, and security hotspots when a Sonar provider is configured |
75
- | Browser E2E | `npm run test:e2e` | Playwright checks map scenario acceptance criteria to visible UI state, API persistence, artifact attachment, responsive layout, and recovery behavior |
76
- | Installed package init | `npm run test:e2e:init` | Installed CLI checks map scenario acceptance criteria to stdout, stderr, exit code, filesystem state, JSON contracts, evidence records, and release-readiness outcomes |
77
- | Runtime manual queue | `npm run test:e2e:runtime` | Temporary-workspace runtime checks prove manual spawn requests queue under delegate pressure and expose queued artifacts through runtime sessions |
78
- | Public site build | `npm run site:build` | production site build |
79
- | Release readiness | `orchestra release check --json` | `releaseReadiness` and `gaReadiness` report |
80
- | Package contents | `npm pack --dry-run --json` | package file list and provenance check |
81
- | Performance budgets | `npm run performance:bench -- --json` | CLI and web API timings on a synthetic large workspace |
68
+ | Flow | Command | Evidence |
69
+ | ---------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
+ | Source quality gate | `npm run precommit` | lint, typecheck, secret scan, security audit, build, unit tests, workflow validation |
71
+ | Secret scanning gate | `npm run secret-scan` | Gitleaks scan with `.gitleaks.toml` when the binary is installed; lightweight fallback for offline local development |
72
+ | Duplicate-code gate | `npm run duplicates` | jscpd duplicate-code report with generated/runtime outputs excluded and collection-standards follow-up for duplicated domain lists |
73
+ | Task split guard | `node --test test/task-split-assessment.test.js` | PO/BA functional oversize, Architect technical complexity, routine small-task non-blocking behavior, and markdown evidence rendering |
74
+ | Sonar quality gate | GitHub Actions: `Sonar` or local SonarQube import | conditional quality gate for duplication, bugs, code smells, maintainability, coverage readiness, and security hotspots when a Sonar provider is configured |
75
+ | Browser E2E | `npm run test:e2e` | Playwright checks map scenario acceptance criteria to visible UI state, API persistence, artifact attachment, responsive layout, and recovery behavior |
76
+ | Installed package init | `npm run test:e2e:init` | Installed CLI checks map scenario acceptance criteria to stdout, stderr, exit code, filesystem state, JSON contracts, evidence records, and release-readiness outcomes |
77
+ | Runtime manual queue | `npm run test:e2e:runtime` | Temporary-workspace runtime checks prove manual spawn requests queue under delegate pressure and expose queued artifacts through runtime sessions |
78
+ | Public site build | `npm run site:build` | production site build |
79
+ | Release readiness | `orchestra release check --json` | `releaseReadiness` and `gaReadiness` report |
80
+ | Package contents | `npm run package:validate` | package file list includes bin, dist, web console, site assets, docs, rules, skills, metadata, and changelog |
81
+ | Performance budgets | `npm run performance:bench -- --json` | CLI and web API timings on a synthetic large workspace |
82
82
 
83
83
  ## Network Policy
84
84
 
@@ -0,0 +1,147 @@
1
+ # Restricted Fragment Storage Contract
2
+
3
+ `GH-510-RESTRICTED-FRAGMENT-STORAGE` defines the future storage envelope for
4
+ retained restricted fragments. This contract does not enable retention by
5
+ default and does not add a vault, KMS, or retrieval product surface.
6
+
7
+ ## Scope
8
+
9
+ Restricted fragment storage is exceptional. It is allowed only when a future
10
+ structured workflow has an approved product need, tenant policy, retention
11
+ class, and security review. Ordinary chat persistence remains redacted-only.
12
+
13
+ The following values must not be retained raw in transcripts, logs, exports,
14
+ evidence, markdown handoffs, telemetry, or provider requests:
15
+
16
+ - credentials, passwords, API keys, tokens, secrets, and signing material
17
+ - payment card data, CVV, track data, and payment account identifiers
18
+ - regulated or sensitive PII unless a future structured policy explicitly
19
+ authorizes encrypted retention
20
+
21
+ ## Storage Boundary
22
+
23
+ Restricted fragments must be stored outside `.agent-workflow/chat/v1` transcript
24
+ JSONL and outside ordinary chat message tables. Chat records may keep only a
25
+ redacted shadow and a restricted-fragment reference.
26
+
27
+ The redacted shadow is the only transcript-safe representation:
28
+
29
+ - fragment id
30
+ - tenant id, workspace id, and source message id
31
+ - classification category and policy id
32
+ - redaction marker and short sanitized summary
33
+ - optional digest of canonical plaintext for dedupe or audit correlation
34
+ - lifecycle status, created timestamp, expiry timestamp, and legal-hold flag
35
+
36
+ The shadow must not contain raw plaintext, ciphertext, encrypted data keys,
37
+ KMS key ids that reveal tenant topology, provider payloads, or debug samples.
38
+
39
+ ## Envelope Encryption
40
+
41
+ Each retained fragment uses envelope encryption:
42
+
43
+ 1. A tenant root key is managed by an external KMS or vault.
44
+ 2. A workspace key-encryption context is derived from tenant id, workspace id,
45
+ retention class, and policy id.
46
+ 3. A fresh per-fragment data encryption key encrypts the fragment with
47
+ `AES-256-GCM` or a reviewed equivalent AEAD.
48
+ 4. The per-fragment data key is wrapped by the workspace key context.
49
+ 5. The ciphertext object stores only ciphertext metadata and the wrapped key
50
+ reference needed for an authorized decrypt operation.
51
+
52
+ The envelope metadata must include:
53
+
54
+ - envelope schema version
55
+ - fragment id and redacted shadow id
56
+ - algorithm, IV/nonce id, authentication tag id, and ciphertext digest
57
+ - wrapped data-key id and key version
58
+ - KMS provider alias and tenant/workspace key scope
59
+ - classification category, retention class, policy id, and purpose
60
+ - creation timestamp, expiry timestamp, and legal-hold flag
61
+
62
+ The envelope metadata must not include raw plaintext, derived plaintext samples,
63
+ complete provider prompts, route request bodies, or user-supplied secret names.
64
+
65
+ ## Audit Contract
66
+
67
+ The append-only audit trail must record sanitized lifecycle events:
68
+
69
+ - `restricted_fragment_detected`
70
+ - `restricted_fragment_shadow_recorded`
71
+ - `restricted_fragment_encrypted`
72
+ - `restricted_fragment_decrypt_denied`
73
+ - `restricted_fragment_restore_attempted`
74
+ - `restricted_fragment_ciphertext_deleted`
75
+ - `restricted_fragment_key_destroyed`
76
+ - `restricted_fragment_crypto_shredded`
77
+ - `restricted_fragment_backup_expiry_pending`
78
+
79
+ Audit entries include tenant id, workspace id, fragment id, policy id, actor id,
80
+ decision id, category, timestamps, and counts. They never include plaintext,
81
+ ciphertext, wrapped key material, provider payloads, or request bodies.
82
+
83
+ ## Crypto-Shred
84
+
85
+ Deleting a retained fragment requires both storage deletion and key destruction:
86
+
87
+ 1. mark the redacted shadow as deletion requested;
88
+ 2. hard-delete the ciphertext object and index entry;
89
+ 3. destroy or disable the fragment data-key binding so decrypt is impossible;
90
+ 4. record the KMS/vault destruction receipt or local equivalent;
91
+ 5. record backup expiry status because immutable backups may age out later;
92
+ 6. record a final `crypto_shredded` audit event.
93
+
94
+ If raw restricted data was blocked and never persisted, delete reports
95
+ `raw_not_persisted` instead of claiming a ciphertext deletion occurred.
96
+
97
+ Crypto-shred is complete only when the active ciphertext object is gone and the
98
+ key binding can no longer unwrap the fragment data key. Backups may still retain
99
+ already-encrypted bytes until their retention windows expire, but those bytes
100
+ must remain unrecoverable once key destruction is complete.
101
+
102
+ ## Restore Constraints
103
+
104
+ Restore is denied by default. A future restore operation must require:
105
+
106
+ - tenant and workspace authorization
107
+ - policy allowing restore for the exact category and retention class
108
+ - legal basis or break-glass reason
109
+ - active key material that has not been crypto-shredded
110
+ - append-only audit before and after the attempt
111
+
112
+ Restore must fail closed when the fragment is expired, the key is destroyed, the
113
+ legal hold conflicts with the request, the actor lacks authorization, or the
114
+ policy does not allow raw recovery. Restored plaintext must be streamed only to
115
+ the authorized consumer and must not be written back into transcripts, evidence,
116
+ logs, exports, or provider prompts.
117
+
118
+ ## Export And Compliance
119
+
120
+ Default chat export remains redacted-only. Export may include redacted shadows
121
+ and audit summaries, but it must not include ciphertext blobs, wrapped keys,
122
+ plaintext, KMS key material, or restoration receipts that expose internals.
123
+ Telemetry, evidence compaction, support bundles, and Markdown reporting follow
124
+ the same rule: only sanitized category, count, marker, decision, and lifecycle
125
+ status data may leave the restricted-fragment boundary.
126
+
127
+ Logical chat tombstones do not satisfy crypto-shred for retained fragments.
128
+ Compliance delete must distinguish:
129
+
130
+ - transcript tombstone only
131
+ - `raw_not_persisted`
132
+ - ciphertext hard delete
133
+ - key destroyed
134
+ - crypto-shred complete
135
+ - backup expiry pending
136
+
137
+ ## Implementation Slices
138
+
139
+ 1. Add storage-agnostic domain types and validation for restricted fragment
140
+ shadows, envelopes, audit events, and delete results.
141
+ 2. Teach chat compliance exports to include redacted shadow summaries while
142
+ excluding ciphertext and wrapped-key metadata.
143
+ 3. Add a storage adapter interface for encrypted fragment object stores.
144
+ 4. Add a KMS/vault adapter interface for wrap, unwrap, disable, and destroy.
145
+ 5. Add delete orchestration that hard-deletes ciphertext before recording key
146
+ destruction and crypto-shred audit events.
147
+ 6. Add restore denial tests before any restore implementation exists.
@@ -75,6 +75,20 @@ OpenAI/Codex provider models are provider-backed execution. `codex-cli` is a
75
75
  runtime-native parent session and never becomes a provider API fallback unless a
76
76
  future explicit hybrid policy records that decision as evidence.
77
77
 
78
+ Before the wrapper creates a provider adapter or sends a request, it evaluates
79
+ provider egress through the security policy boundary. Messages are classified
80
+ through the shared classifier/redaction contract and treated as a `provider`
81
+ sink. Restricted or unsafe-unredacted content is blocked before any provider
82
+ call; only sanitized policy metadata may be recorded as evidence. Provider
83
+ failure messages are sanitized before surfacing so backend base URLs,
84
+ authorization headers, API keys, and token-shaped values are not exposed.
85
+
86
+ Internal providers such as `ollama` are private-only. `OLLAMA_BASE_URL` must be
87
+ server-configured and point at `localhost`, loopback, link-local, or RFC1918
88
+ private-network IP addresses. Public DNS names and public IPs are rejected by
89
+ policy. Use loopback for local development, or a private address reachable only
90
+ inside the trusted deployment network.
91
+
78
92
  ## Init Modes
79
93
 
80
94
  Default project init keeps the current compact bootstrap behavior:
@@ -487,13 +501,26 @@ agent path and records that choice in phase provenance.
487
501
 
488
502
  When no task or role executor is configured and the default executor is
489
503
  `generic-runtime`, `auto` and strict `subagents` mode infer the active runtime
490
- from `OPEN_ORCHESTRA_ACTIVE_RUNTIME`, known parent-runtime environment markers,
491
- or managed runtime bootstrap files. Codex maps to `codex-cli`, Claude maps to
492
- `claude-cli`, Cursor maps to `cursor-cli`, Windsurf maps to `windsurf-agent`,
493
- and VS Code maps to `vscode-agent`.
494
-
495
- Explicit selections always take precedence in this order: `--runtime`, task
496
- override, role override, then `runtimePolicy.defaults.executor`. Automatic
504
+ from `.agent-workflow/active-runtime.json`, then from `OPEN_ORCHESTRA_ACTIVE_RUNTIME`
505
+ as a final fallback for non-hook environments (CI, scripts).
506
+
507
+ `.agent-workflow/active-runtime.json` is the truthful signal of which AI runtime
508
+ is currently driving the conversation. It is written by the active runtime's
509
+ UserPromptSubmit hook on every session start. `orchestra init --target claude`
510
+ configures Claude's `.claude/settings.json` hook to call
511
+ `orchestra health --runtime claude-cli --json`; `--target cursor` configures the
512
+ equivalent in `.cursor/rules/orchestra-health.mdc`. Manual-setup guidance for
513
+ Codex/VS Code/Windsurf documents the same `orchestra health --runtime <id>`
514
+ pattern that must run at session start. Each hook overwrites the file with its
515
+ own runtime id, so "last writer wins" matches "current parent runtime".
516
+
517
+ The persisted record has a 24h TTL. Records older than that are ignored and
518
+ inference falls through to the next signal. Codex maps to `codex-cli`, Claude
519
+ maps to `claude-cli`, Cursor maps to `cursor-cli`, Windsurf maps to
520
+ `windsurf-agent`, and VS Code maps to `vscode-agent`.
521
+
522
+ Explicit selections always take precedence in this order: `--runtime` flag,
523
+ task override, role override, then `runtimePolicy.defaults.executor`. Automatic
497
524
  inference never rewrites `.agent-workflow/config.json`; it only affects the
498
525
  current planning decision. Set `workflow.phaseExecutionMode` to `single-agent`
499
526
  or configure `runtimePolicy.defaults.executor` to override inference for
@@ -501,6 +528,12 @@ deterministic local or CI runs. If `OPEN_ORCHESTRA_ACTIVE_RUNTIME` names an
501
528
  unknown runtime, workflow planning fails with supported values and the same
502
529
  override options instead of requiring hidden config edits.
503
530
 
531
+ File-based inference (reading `target=` from `AGENTS.md`/`CLAUDE.md`/etc.) and
532
+ per-tool environment detection (`CLAUDECODE`, `CODEX_THREAD_ID`,
533
+ `CURSOR_TRACE_ID`, etc.) are intentionally **not** used: instruction files
534
+ describe which runtimes the project supports, not which one is active right
535
+ now, and per-tool env vars can coexist in nested or inherited sessions.
536
+
504
537
  Subagent spawning is fully asynchronous by default. A spawn request returns the
505
538
  `sessionId`, request artifact, prompt artifact, expected result artifact, status,
506
539
  next lifecycle commands, and quality warnings, then the parent agent should
@@ -519,6 +552,13 @@ workflow after capacity is released. Manual `runtime spawn-request` calls follow
519
552
  the same guardrails: `queue` materializes a queued request artifact and session,
520
553
  while `reject` fails before creating a delegation artifact.
521
554
 
555
+ Default local runtime-native guardrails allow 3 concurrent delegated sessions
556
+ and 3 spawns per task. The separate SaaS-capacity scheduler defaults to 3 active
557
+ runtime leases, 25 queued requests, 2 active requests per provider, and 3 active
558
+ requests per runtime within the evaluated platform, tenant, and workspace
559
+ policies. Hosted deployments should override those thresholds per tenant and
560
+ workspace before enabling runtime-native dispatch.
561
+
522
562
  For multi-squad work, the parent renders one spawn request per independent
523
563
  squad/role/phase. Each detached session is tracked independently by `sessionId`;
524
564
  completion order is intentionally non-deterministic. Release aggregation,
@@ -0,0 +1,57 @@
1
+ # Runtime Capacity Model
2
+
3
+ Open Orchestra runtime capacity is modeled as a deterministic local-first
4
+ contract. Local runs use the implicit `local/local/local-workspace` scope; SaaS
5
+ mode requires every request, queue item, lease, event, and snapshot to carry
6
+ tenant and workspace scope.
7
+
8
+ ## Core Concepts
9
+
10
+ - `RuntimeCapacityScope`: platform, tenant, and workspace identity.
11
+ - `RuntimeWorkloadClass`: interactive, workflow phase, runtime-native spawn,
12
+ provider-backed phase, background maintenance, or evidence processing.
13
+ - `RuntimeCapacityUnit`: weighted runtime demand, currently enforced by
14
+ `concurrencyUnits` with optional budget and resource hints.
15
+ - `RuntimeQuotaPolicy`: platform, tenant, and workspace active/queued limits,
16
+ provider/runtime caps, and queue/reject behavior.
17
+ - `RuntimeWorkerRecord`: registered worker capabilities, tenant affinity,
18
+ regions, supported providers/runtimes/workload classes, health, capacity, and
19
+ isolation metadata.
20
+
21
+ ## Scheduler Decisions
22
+
23
+ `RuntimeCapacityScheduler.schedule()` returns one typed decision:
24
+
25
+ - `admitted`: a `RuntimeLease` was granted for a specific worker.
26
+ - `queued`: quota or worker capacity can recover and the request is accepted
27
+ into a scoped queue.
28
+ - `rejected`: the request is invalid or the configured policy does not allow
29
+ queueing.
30
+ - `deferred`: no eligible worker is available and queueing is disabled.
31
+
32
+ Evaluation is fail-closed: request validation, SaaS scope, platform quota,
33
+ tenant quota, workspace quota, provider/runtime caps, then worker selection.
34
+ Queue limits are enforced at platform, tenant, and workspace levels before a
35
+ queue decision is returned.
36
+
37
+ ## Load Balancing
38
+
39
+ Worker selection is constraint-first and score-second. Eligibility checks tenant
40
+ affinity, denied tenants, workload class, runtime/provider support, region and
41
+ data residency, health, heartbeat freshness, open circuits, and available
42
+ capacity. Scoring is deterministic: available capacity, queue depth, failure
43
+ count, region preference, health, and tenant affinity are sorted with worker id
44
+ as the final tie breaker.
45
+
46
+ ## Isolation
47
+
48
+ SaaS mode rejects missing tenant/workspace scope. Snapshots can be filtered by
49
+ scope so tenant-facing queue evidence does not expose other tenants. Decision
50
+ messages use stable reason codes and user-safe summaries rather than worker
51
+ internals, queue depths from other tenants, paths, or provider details.
52
+
53
+ ## Current Boundary
54
+
55
+ This story intentionally keeps capacity state in memory. Hosted queues,
56
+ transactional worker leases, tenant-secret routing, and data residency
57
+ persistence remain follow-up architecture and security work before SaaS release.