@abot-ai/runtime 1.1.0 → 1.2.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 (268) hide show
  1. package/README.md +6 -3
  2. package/dist/src/capabilities/tool-types.d.ts +1 -1
  3. package/dist/src/model-gateway/providers/ollama/generation-options.d.ts +1 -3
  4. package/dist/src/model-gateway/providers/ollama/generation-options.js +1 -5
  5. package/dist/src/model-gateway/providers/ollama/payload.js +0 -8
  6. package/dist/src/model-gateway/server/request-body.js +1 -0
  7. package/dist/src/plugin-sdk/index.d.ts +2 -0
  8. package/dist/src/plugin-sdk/index.js +2 -0
  9. package/dist/src/plugin-sdk/tool-availability-brief.d.ts +9 -0
  10. package/dist/src/plugin-sdk/tool-availability-brief.js +48 -0
  11. package/dist/src/plugin-sdk/tool-availability-overview.d.ts +9 -0
  12. package/dist/src/plugin-sdk/tool-availability-overview.js +62 -0
  13. package/dist/src/runtime/adapters/registered-tool-payload-plan.d.ts +0 -9
  14. package/dist/src/runtime/adapters/registered-tool-payload-plan.js +0 -67
  15. package/dist/src/runtime/adapters/registered-tool-payload-related-artifacts.d.ts +13 -0
  16. package/dist/src/runtime/adapters/registered-tool-payload-related-artifacts.js +84 -0
  17. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/catalog.js +4 -0
  18. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/execution.js +3 -0
  19. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-lifecycle.d.ts +1 -0
  20. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-lifecycle.js +11 -1
  21. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-stages.d.ts +1 -0
  22. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-stages.js +9 -1
  23. package/dist/src/runtime/capabilities/request-bound-tool-registry.js +1 -24
  24. package/dist/src/runtime/capabilities/tool-availability.d.ts +6 -0
  25. package/dist/src/runtime/capabilities/tool-availability.js +28 -0
  26. package/dist/src/runtime/context/capability-brief.d.ts +25 -0
  27. package/dist/src/runtime/context/capability-brief.js +106 -0
  28. package/dist/src/runtime/context/request-tool-results-message-binding.d.ts +6 -0
  29. package/dist/src/runtime/context/request-tool-results-message-binding.js +30 -0
  30. package/dist/src/runtime/context/request-tool-results-scope.d.ts +3 -0
  31. package/dist/src/runtime/context/request-tool-results-scope.js +8 -0
  32. package/dist/src/runtime/context/request-tool-results.d.ts +8 -4
  33. package/dist/src/runtime/context/request-tool-results.js +49 -38
  34. package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +8 -1
  35. package/dist/src/runtime/orchestration/role-calls/child-return.d.ts +4 -0
  36. package/dist/src/runtime/orchestration/role-calls/child-return.js +25 -5
  37. package/dist/src/runtime/orchestration/role-calls/command-decoder.js +8 -3
  38. package/dist/src/runtime/orchestration/role-calls/command-dispatch/child-transitions.d.ts +1 -1
  39. package/dist/src/runtime/orchestration/role-calls/command-dispatch/child-transitions.js +17 -2
  40. package/dist/src/runtime/orchestration/role-calls/command-dispatch.d.ts +1 -1
  41. package/dist/src/runtime/orchestration/role-calls/command-dispatch.js +2 -2
  42. package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +5 -2
  43. package/dist/src/runtime/orchestration/role-calls/contracts.js +4 -4
  44. package/dist/src/runtime/orchestration/role-calls/dependency-results.d.ts +1 -1
  45. package/dist/src/runtime/orchestration/role-calls/dependency-results.js +1 -0
  46. package/dist/src/runtime/orchestration/role-calls/index.d.ts +5 -1
  47. package/dist/src/runtime/orchestration/role-calls/index.js +5 -1
  48. package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +3 -1
  49. package/dist/src/runtime/orchestration/role-calls/ledger.js +9 -2
  50. package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
  51. package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -2
  52. package/dist/src/runtime/orchestration/role-calls/result-receipt.d.ts +49 -0
  53. package/dist/src/runtime/orchestration/role-calls/result-receipt.js +188 -0
  54. package/dist/src/runtime/orchestration/role-calls/return-result-receipt.d.ts +19 -0
  55. package/dist/src/runtime/orchestration/role-calls/return-result-receipt.js +52 -0
  56. package/dist/src/runtime/orchestration/role-calls/transactions.js +1 -0
  57. package/dist/src/runtime/orchestration/role-calls/work-result-lineage.d.ts +34 -0
  58. package/dist/src/runtime/orchestration/role-calls/work-result-lineage.js +185 -0
  59. package/dist/src/runtime/orchestration/role-calls/work-result-receipt.d.ts +36 -0
  60. package/dist/src/runtime/orchestration/role-calls/work-result-receipt.js +187 -0
  61. package/dist/src/runtime/orchestration/role-executors/activation/result-normalization.js +6 -3
  62. package/dist/src/runtime/orchestration/role-executors/child-invocation/transaction.js +1 -0
  63. package/dist/src/runtime/orchestration/role-executors/contracts.d.ts +2 -1
  64. package/dist/src/runtime/orchestration/worker-capabilities/assignment-provenance.d.ts +36 -0
  65. package/dist/src/runtime/orchestration/worker-capabilities/assignment-provenance.js +171 -0
  66. package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +32 -1
  67. package/dist/src/runtime/orchestration/worker-capabilities/execution/invocation-preparation.d.ts +2 -1
  68. package/dist/src/runtime/orchestration/worker-capabilities/execution/invocation-preparation.js +3 -0
  69. package/dist/src/runtime/orchestration/worker-capabilities/execution.js +42 -19
  70. package/dist/src/runtime/orchestration/worker-capabilities/index.d.ts +2 -0
  71. package/dist/src/runtime/orchestration/worker-capabilities/index.js +2 -0
  72. package/dist/src/runtime/orchestration/worker-capabilities/payload-assignment-validation.d.ts +3 -0
  73. package/dist/src/runtime/orchestration/worker-capabilities/payload-assignment-validation.js +30 -0
  74. package/dist/src/runtime/orchestration/worker-capabilities/payload-author.js +8 -19
  75. package/dist/src/runtime/orchestration/worker-capabilities/payload-contracts.d.ts +5 -1
  76. package/dist/src/runtime/orchestration/worker-capabilities/payload-instructions.js +1 -1
  77. package/dist/src/runtime/orchestration/worker-capabilities/payload-source-provenance.d.ts +14 -0
  78. package/dist/src/runtime/orchestration/worker-capabilities/payload-source-provenance.js +132 -0
  79. package/dist/src/runtime/request/capability-brief.d.ts +5 -0
  80. package/dist/src/runtime/request/capability-brief.js +24 -0
  81. package/dist/src/runtime/request/execution-scope.d.ts +2 -1
  82. package/dist/src/runtime/request/role-executor-composition.js +1 -1
  83. package/dist/src/runtime/request/worker-capability-composition.d.ts +2 -1
  84. package/dist/src/runtime/request/worker-capability-composition.js +6 -1
  85. package/dist/src/runtime/request/worker-capability-payload.js +11 -8
  86. package/dist/src/runtime/steps/execution-agent/prompt.js +4 -3
  87. package/dist/src/runtime/steps/planner-decision/capability-catalog-context.d.ts +14 -0
  88. package/dist/src/runtime/steps/planner-decision/capability-catalog-context.js +87 -0
  89. package/dist/src/runtime/steps/planner-decision/contracts.d.ts +3 -5
  90. package/dist/src/runtime/steps/planner-decision/contracts.js +3 -3
  91. package/dist/src/runtime/steps/planner-decision/format.d.ts +3 -2
  92. package/dist/src/runtime/steps/planner-decision/format.js +73 -76
  93. package/dist/src/runtime/steps/planner-decision/input.d.ts +4 -3
  94. package/dist/src/runtime/steps/planner-decision/input.js +10 -7
  95. package/dist/src/runtime/steps/planner-decision/parser.d.ts +3 -2
  96. package/dist/src/runtime/steps/planner-decision/parser.js +10 -19
  97. package/dist/src/runtime/steps/planner-decision/plan-parser.js +18 -12
  98. package/dist/src/runtime/steps/planner-decision/prompt.js +33 -28
  99. package/dist/src/runtime/steps/planner-decision/resume.d.ts +1 -1
  100. package/dist/src/runtime/steps/planner-decision/resume.js +38 -1
  101. package/dist/src/runtime/steps/planner-decision/run.d.ts +3 -2
  102. package/dist/src/runtime/steps/reviewer-decision/audit-coverage.d.ts +10 -0
  103. package/dist/src/runtime/steps/reviewer-decision/audit-coverage.js +186 -0
  104. package/dist/src/runtime/steps/reviewer-decision/contracts.d.ts +3 -8
  105. package/dist/src/runtime/steps/reviewer-decision/contracts.js +12 -6
  106. package/dist/src/runtime/steps/reviewer-decision/delegated-context.d.ts +24 -0
  107. package/dist/src/runtime/steps/reviewer-decision/delegated-context.js +70 -0
  108. package/dist/src/runtime/steps/reviewer-decision/diagnostics.js +1 -1
  109. package/dist/src/runtime/steps/reviewer-decision/format.js +37 -24
  110. package/dist/src/runtime/steps/reviewer-decision/input.js +1 -1
  111. package/dist/src/runtime/steps/reviewer-decision/model-context.d.ts +4 -3
  112. package/dist/src/runtime/steps/reviewer-decision/model-context.js +92 -10
  113. package/dist/src/runtime/steps/reviewer-decision/parser.js +19 -1
  114. package/dist/src/runtime/steps/reviewer-decision/projection.js +42 -68
  115. package/dist/src/runtime/steps/reviewer-decision/prompt.js +10 -5
  116. package/dist/src/runtime/steps/reviewer-decision/run.js +12 -3
  117. package/dist/src/runtime/steps/reviewer-decision/verification-coverage.d.ts +14 -0
  118. package/dist/src/runtime/steps/reviewer-decision/verification-coverage.js +52 -0
  119. package/dist/src/runtime/steps/supervisor-decision/capability-brief.d.ts +14 -0
  120. package/dist/src/runtime/steps/supervisor-decision/capability-brief.js +38 -0
  121. package/dist/src/runtime/steps/supervisor-decision/contracts.d.ts +7 -3
  122. package/dist/src/runtime/steps/supervisor-decision/diagnostics.d.ts +2 -0
  123. package/dist/src/runtime/steps/supervisor-decision/diagnostics.js +8 -2
  124. package/dist/src/runtime/steps/supervisor-decision/format.js +32 -20
  125. package/dist/src/runtime/steps/supervisor-decision/input.d.ts +4 -1
  126. package/dist/src/runtime/steps/supervisor-decision/input.js +19 -1
  127. package/dist/src/runtime/steps/supervisor-decision/parser.js +62 -59
  128. package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -7
  129. package/dist/src/runtime/steps/supervisor-decision/resume.js +47 -1
  130. package/dist/src/runtime/steps/supervisor-decision/run.js +10 -0
  131. package/dist/src/runtime/steps/supervisor-decision/working-directory.js +2 -1
  132. package/dist/src/runtime/steps/worker-decision/contracts.d.ts +2 -1
  133. package/dist/src/runtime/steps/worker-decision/input/canonical-state.js +8 -1
  134. package/dist/src/runtime/steps/worker-decision/input/diagnostic-projection.js +2 -2
  135. package/dist/src/runtime/steps/worker-decision/input/prompt-context.d.ts +1 -0
  136. package/dist/src/runtime/steps/worker-decision/input/prompt-context.js +4 -1
  137. package/dist/src/runtime/steps/worker-decision/input/reference-context.js +34 -14
  138. package/dist/src/runtime/steps/worker-decision/input/types.d.ts +2 -1
  139. package/dist/src/runtime/steps/worker-decision/input.d.ts +1 -0
  140. package/dist/src/runtime/steps/worker-decision/input.js +1 -0
  141. package/dist/src/runtime/steps/worker-decision/payload-dependency-results.d.ts +8 -0
  142. package/dist/src/runtime/steps/worker-decision/payload-dependency-results.js +19 -0
  143. package/dist/src/runtime/steps/worker-decision/prompt.js +8 -8
  144. package/dist/src/runtime/steps/worker-decision/result-author.js +18 -11
  145. package/dist/src/runtime/steps/worker-decision/run.js +2 -2
  146. package/dist/src/web-ui/app/ARCHITECTURE.md +19 -6
  147. package/dist/src/web-ui/app/app.js +6 -7
  148. package/dist/src/web-ui/app/components/composer-context-window.d.ts +25 -0
  149. package/dist/src/web-ui/app/components/composer-context-window.js +155 -0
  150. package/dist/src/web-ui/app/components/composer-plan.d.ts +9 -0
  151. package/dist/src/web-ui/app/components/composer-plan.js +128 -0
  152. package/dist/src/web-ui/app/components/conversation-activity.d.ts +5 -6
  153. package/dist/src/web-ui/app/components/conversation-activity.js +64 -157
  154. package/dist/src/web-ui/app/components/conversation-role-cards.d.ts +23 -0
  155. package/dist/src/web-ui/app/components/conversation-role-cards.js +181 -0
  156. package/dist/src/web-ui/app/components/conversation-sidebar-layout.js +12 -0
  157. package/dist/src/web-ui/app/components/conversation-sources.d.ts +7 -0
  158. package/dist/src/web-ui/app/components/conversation-sources.js +182 -0
  159. package/dist/src/web-ui/app/components/conversation-view.js +34 -6
  160. package/dist/src/web-ui/app/components/model-selector.js +4 -1
  161. package/dist/src/web-ui/app/components/operations-section.js +46 -0
  162. package/dist/src/web-ui/app/components/workspace-shell.js +86 -78
  163. package/dist/src/web-ui/app/controllers/realtime-event-controller.d.ts +1 -0
  164. package/dist/src/web-ui/app/controllers/realtime-event-controller.js +55 -90
  165. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +2 -0
  166. package/dist/src/web-ui/app/controllers/session-controller.js +17 -12
  167. package/dist/src/web-ui/app/index.html +209 -210
  168. package/dist/src/web-ui/app/lib/composer-plan-model.d.ts +32 -0
  169. package/dist/src/web-ui/app/lib/composer-plan-model.js +108 -0
  170. package/dist/src/web-ui/app/lib/conversation-role-model.d.ts +19 -0
  171. package/dist/src/web-ui/app/lib/conversation-role-model.js +193 -0
  172. package/dist/src/web-ui/app/lib/event-presentation.js +30 -9
  173. package/dist/src/web-ui/app/lib/source-url-policy.d.ts +2 -0
  174. package/dist/src/web-ui/app/lib/source-url-policy.js +31 -0
  175. package/dist/src/web-ui/app/lib/task-progress.d.ts +53 -0
  176. package/dist/src/web-ui/app/lib/task-progress.js +233 -0
  177. package/dist/src/web-ui/app/lib/tool-invocation-count.d.ts +5 -0
  178. package/dist/src/web-ui/app/lib/tool-invocation-count.js +21 -0
  179. package/dist/src/web-ui/app/lib/web-source-event.d.ts +8 -0
  180. package/dist/src/web-ui/app/lib/web-source-event.js +21 -0
  181. package/dist/src/web-ui/app/lib/web-sources.d.ts +36 -0
  182. package/dist/src/web-ui/app/lib/web-sources.js +177 -0
  183. package/dist/src/web-ui/app/styles/00-tokens-base.css +15 -3
  184. package/dist/src/web-ui/app/styles/10-shell-sessions.css +24 -34
  185. package/dist/src/web-ui/app/styles/12-conversation-sidebar.css +93 -0
  186. package/dist/src/web-ui/app/styles/20-chat-composer.css +55 -472
  187. package/dist/src/web-ui/app/styles/21-composer-controls.css +368 -0
  188. package/dist/src/web-ui/app/styles/22-composer-context-window.css +90 -0
  189. package/dist/src/web-ui/app/styles/23-composer-plan.css +171 -0
  190. package/dist/src/web-ui/app/styles/24-conversation-role-cards.css +205 -0
  191. package/dist/src/web-ui/app/styles/25-conversation-sources.css +141 -0
  192. package/dist/src/web-ui/app/styles/30-inspector-config.css +21 -209
  193. package/dist/src/web-ui/app/styles/35-memory-onboarding.css +8 -8
  194. package/dist/src/web-ui/app/styles/36-memory-management.css +13 -13
  195. package/dist/src/web-ui/app/styles/37-config-operations.css +197 -0
  196. package/dist/src/web-ui/app/styles/40-config-workspace.css +36 -36
  197. package/dist/src/web-ui/app/styles/90-responsive.css +14 -77
  198. package/dist/src/web-ui/app/styles/foundation.css +2 -2
  199. package/dist/src/web-ui/app/styles.css +7 -0
  200. package/dist/src/web-ui/app/ui-behavior.d.ts +1 -1
  201. package/dist/src/web-ui/app/ui-behavior.js +1 -1
  202. package/docs/configuration.md +15 -8
  203. package/docs/installation.md +7 -4
  204. package/docs/known-limitations.md +21 -0
  205. package/docs/plugins.md +28 -13
  206. package/docs/runtime-invariant-coverage.md +18 -17
  207. package/docs/runtime-prompt-policy-contracts.md +27 -17
  208. package/package.json +4 -3
  209. package/plugins/capability-brief/source/index.ts +5 -48
  210. package/plugins/capability-brief/src/index.cjs +46 -33
  211. package/plugins/system-probe/plugin.json +1 -0
  212. package/plugins/web/README.md +125 -0
  213. package/plugins/web/plugin.json +1 -1
  214. package/plugins/web/skills/web_fetch_skill/SKILL.md +2 -2
  215. package/plugins/web/skills/web_search_skill/SKILL.md +8 -4
  216. package/plugins/web/source/errors.ts +5 -1
  217. package/plugins/web/source/fetch-presentation.ts +61 -0
  218. package/plugins/web/source/fetch-service.ts +2 -31
  219. package/plugins/web/source/light/config.ts +196 -0
  220. package/plugins/web/source/light/crawl/origin-gate.ts +134 -0
  221. package/plugins/web/source/light/crawl/robots-cache.ts +71 -0
  222. package/plugins/web/source/light/crawl/robots-parser.ts +132 -0
  223. package/plugins/web/source/light/crawl/robots-policy.ts +154 -0
  224. package/plugins/web/source/light/crawl/session-budget.ts +141 -0
  225. package/plugins/web/source/light/crawl/transport.ts +216 -0
  226. package/plugins/web/source/light/discovery/candidate-values.ts +63 -0
  227. package/plugins/web/source/light/discovery/feed-document.ts +127 -0
  228. package/plugins/web/source/light/discovery/html-links.ts +80 -0
  229. package/plugins/web/source/light/discovery/html-robots-directives.ts +29 -0
  230. package/plugins/web/source/light/discovery/markup-tree.ts +145 -0
  231. package/plugins/web/source/light/discovery/origin-dates.ts +71 -0
  232. package/plugins/web/source/light/discovery/sitemap-document.ts +63 -0
  233. package/plugins/web/source/light/documents/cache-policy.ts +28 -0
  234. package/plugins/web/source/light/documents/document-cache.ts +99 -0
  235. package/plugins/web/source/light/documents/document-charset.ts +89 -0
  236. package/plugins/web/source/light/documents/document-contract.ts +20 -0
  237. package/plugins/web/source/light/documents/document-reader.ts +75 -0
  238. package/plugins/web/source/light/documents/extract-document.ts +124 -0
  239. package/plugins/web/source/light/documents/http-cache-freshness.ts +68 -0
  240. package/plugins/web/source/light/documents/response-decoding.ts +120 -0
  241. package/plugins/web/source/light/ranking/document-ranking.ts +114 -0
  242. package/plugins/web/source/light/ranking/query-normalization.ts +69 -0
  243. package/plugins/web/source/light/search-collection.ts +136 -0
  244. package/plugins/web/source/light/search-frontier.ts +246 -0
  245. package/plugins/web/source/light/search-metadata.ts +84 -0
  246. package/plugins/web/source/light/search-service.ts +154 -0
  247. package/plugins/web/source/light/search-unavailable.ts +33 -0
  248. package/plugins/web/source/light/sources/catalog.ts +312 -0
  249. package/plugins/web/source/light/sources/source-definition.ts +9 -0
  250. package/plugins/web/source/light/sources/source-selection.ts +35 -0
  251. package/plugins/web/source/plugin.ts +70 -56
  252. package/plugins/web/source/public-http.ts +10 -1
  253. package/plugins/web/source/search-presentation.ts +63 -63
  254. package/plugins/web/source/search-service-selector.ts +31 -0
  255. package/plugins/web/source/search-service.ts +6 -0
  256. package/plugins/web/source/search-source-presentation.ts +76 -0
  257. package/plugins/web/source/search-types.ts +4 -0
  258. package/plugins/web/source/source-output-receipts.ts +267 -0
  259. package/plugins/web/source/source-receipt-budget.ts +51 -0
  260. package/plugins/web/source/source-receipt-contract.ts +18 -0
  261. package/plugins/web/src/index.cjs +3214 -288
  262. package/src/runtime/README.md +30 -9
  263. package/dist/src/model-gateway/structured-output/budget.d.ts +0 -7
  264. package/dist/src/model-gateway/structured-output/budget.js +0 -20
  265. package/dist/src/model-gateway/structured-output/schema-character-estimator.d.ts +0 -1
  266. package/dist/src/model-gateway/structured-output/schema-character-estimator.js +0 -211
  267. package/dist/src/model-gateway/structured-output-budget.d.ts +0 -1
  268. package/dist/src/model-gateway/structured-output-budget.js +0 -1
@@ -0,0 +1,10 @@
1
+ import { type ReviewerDecisionValidationIssue, type ReviewerReviewSnapshot } from "./contracts.js";
2
+ export declare const REVIEWER_AUDIT_FINDING_MAX_LENGTH = 512;
3
+ export type ReviewerAuditCoverage = Readonly<{
4
+ requiresGapVerdict: boolean;
5
+ completionEvidenceRefCount: number;
6
+ }>;
7
+ export declare function createReviewerAuditCoverageSchema(snapshot: ReviewerReviewSnapshot, options: Readonly<{
8
+ minimumCompletionEvidenceRefs: number;
9
+ }>): Record<string, unknown>;
10
+ export declare function parseReviewerAuditCoverage(value: unknown, snapshot: ReviewerReviewSnapshot, issues: ReviewerDecisionValidationIssue[]): ReviewerAuditCoverage | undefined;
@@ -0,0 +1,186 @@
1
+ import { REVIEWER_MAX_EVIDENCE, } from "./contracts.js";
2
+ export const REVIEWER_AUDIT_FINDING_MAX_LENGTH = 512;
3
+ const EVIDENCE_ASSESSMENT_STATUSES = Object.freeze([
4
+ "supports",
5
+ "does_not_establish",
6
+ "contradicts",
7
+ ]);
8
+ const COMPLETION_ASSESSMENT_STATUSES = Object.freeze([
9
+ "satisfied",
10
+ "gap",
11
+ "indeterminate",
12
+ ]);
13
+ export function createReviewerAuditCoverageSchema(snapshot, options) {
14
+ const evidenceRefs = snapshot.evidence.map(({ evidenceRef }) => evidenceRef);
15
+ return exactObject({
16
+ evidenceAssessments: {
17
+ type: "array",
18
+ minItems: evidenceRefs.length,
19
+ maxItems: evidenceRefs.length,
20
+ items: exactObject({
21
+ evidenceRef: enumString(evidenceRefs),
22
+ status: enumString(EVIDENCE_ASSESSMENT_STATUSES),
23
+ finding: boundedText(REVIEWER_AUDIT_FINDING_MAX_LENGTH),
24
+ }),
25
+ },
26
+ completionAssessment: exactObject({
27
+ status: enumString(COMPLETION_ASSESSMENT_STATUSES),
28
+ evidenceRefs: {
29
+ type: "array",
30
+ minItems: options.minimumCompletionEvidenceRefs,
31
+ maxItems: evidenceRefs.length,
32
+ items: enumString(evidenceRefs),
33
+ },
34
+ finding: boundedText(REVIEWER_AUDIT_FINDING_MAX_LENGTH),
35
+ }),
36
+ });
37
+ }
38
+ export function parseReviewerAuditCoverage(value, snapshot, issues) {
39
+ const record = asRecord(value);
40
+ if (!record) {
41
+ issues.push(issue("reviewer_audit_invalid", "decision.audit"));
42
+ return undefined;
43
+ }
44
+ exactKeys(record, ["evidenceAssessments", "completionAssessment"], "decision.audit", issues);
45
+ const evidenceAssessment = parseEvidenceAssessments(record.evidenceAssessments, snapshot, issues);
46
+ const completionAssessment = parseCompletionAssessment(record.completionAssessment, snapshot, issues);
47
+ if (!evidenceAssessment || !completionAssessment)
48
+ return undefined;
49
+ return Object.freeze({
50
+ requiresGapVerdict: evidenceAssessment.hasContradiction ||
51
+ completionAssessment.status !== "satisfied",
52
+ completionEvidenceRefCount: completionAssessment.evidenceRefCount,
53
+ });
54
+ }
55
+ function parseEvidenceAssessments(value, snapshot, issues) {
56
+ if (!Array.isArray(value) ||
57
+ value.length !== snapshot.evidence.length ||
58
+ value.length > REVIEWER_MAX_EVIDENCE) {
59
+ issues.push(issue("reviewer_evidence_assessment_coverage_invalid", "decision.audit.evidenceAssessments"));
60
+ return undefined;
61
+ }
62
+ const allowedRefs = new Set(snapshot.evidence.map(({ evidenceRef }) => evidenceRef));
63
+ const assessedRefs = new Set();
64
+ let hasContradiction = false;
65
+ value.forEach((entry, index) => {
66
+ const path = `decision.audit.evidenceAssessments[${index}]`;
67
+ const assessment = asRecord(entry);
68
+ if (!assessment) {
69
+ issues.push(issue("reviewer_evidence_assessment_invalid", path));
70
+ return;
71
+ }
72
+ exactKeys(assessment, ["evidenceRef", "status", "finding"], path, issues);
73
+ const evidenceRef = assessment.evidenceRef;
74
+ if (typeof evidenceRef !== "string" || !allowedRefs.has(evidenceRef)) {
75
+ issues.push(issue("reviewer_evidence_assessment_ref_unknown", `${path}.evidenceRef`));
76
+ }
77
+ else if (assessedRefs.has(evidenceRef)) {
78
+ issues.push(issue("reviewer_evidence_assessment_ref_duplicate", `${path}.evidenceRef`));
79
+ }
80
+ else {
81
+ assessedRefs.add(evidenceRef);
82
+ }
83
+ const status = assessment.status;
84
+ if (!isEvidenceAssessmentStatus(status)) {
85
+ issues.push(issue("reviewer_evidence_assessment_status_invalid", `${path}.status`));
86
+ }
87
+ else if (status === "contradicts") {
88
+ hasContradiction = true;
89
+ }
90
+ parseFinding(assessment.finding, `${path}.finding`, issues);
91
+ });
92
+ if (assessedRefs.size !== allowedRefs.size) {
93
+ issues.push(issue("reviewer_evidence_assessment_coverage_invalid", "decision.audit.evidenceAssessments"));
94
+ }
95
+ return Object.freeze({ hasContradiction });
96
+ }
97
+ function parseCompletionAssessment(value, snapshot, issues) {
98
+ const record = asRecord(value);
99
+ if (!record) {
100
+ issues.push(issue("reviewer_completion_assessment_invalid", "decision.audit.completionAssessment"));
101
+ return undefined;
102
+ }
103
+ exactKeys(record, ["status", "evidenceRefs", "finding"], "decision.audit.completionAssessment", issues);
104
+ const status = record.status;
105
+ if (!isCompletionAssessmentStatus(status)) {
106
+ issues.push(issue("reviewer_completion_assessment_status_invalid", "decision.audit.completionAssessment.status"));
107
+ }
108
+ const evidenceRefCount = parseEvidenceRefs(record.evidenceRefs, snapshot, "decision.audit.completionAssessment.evidenceRefs", issues);
109
+ parseFinding(record.finding, "decision.audit.completionAssessment.finding", issues);
110
+ return isCompletionAssessmentStatus(status)
111
+ ? Object.freeze({ status, evidenceRefCount })
112
+ : undefined;
113
+ }
114
+ function parseEvidenceRefs(value, snapshot, path, issues) {
115
+ if (!Array.isArray(value) || value.length > snapshot.evidence.length) {
116
+ issues.push(issue("reviewer_audit_evidence_refs_invalid", path));
117
+ return 0;
118
+ }
119
+ const allowed = new Set(snapshot.evidence.map(({ evidenceRef }) => evidenceRef));
120
+ const seen = new Set();
121
+ value.forEach((entry, index) => {
122
+ if (typeof entry !== "string" || !allowed.has(entry)) {
123
+ issues.push(issue("reviewer_audit_evidence_ref_unknown", `${path}[${index}]`));
124
+ }
125
+ else if (seen.has(entry)) {
126
+ issues.push(issue("reviewer_audit_evidence_ref_duplicate", `${path}[${index}]`));
127
+ }
128
+ else {
129
+ seen.add(entry);
130
+ }
131
+ });
132
+ return seen.size;
133
+ }
134
+ function parseFinding(value, path, issues) {
135
+ const normalized = typeof value === "string" ? value.trim() : "";
136
+ if (normalized.length === 0 ||
137
+ /[\u0000-\u001F\u007F\uD800-\uDFFF]/u.test(normalized)) {
138
+ issues.push(issue("reviewer_audit_finding_invalid", path));
139
+ }
140
+ }
141
+ function isEvidenceAssessmentStatus(value) {
142
+ return (typeof value === "string" &&
143
+ EVIDENCE_ASSESSMENT_STATUSES.includes(value));
144
+ }
145
+ function isCompletionAssessmentStatus(value) {
146
+ return (typeof value === "string" &&
147
+ COMPLETION_ASSESSMENT_STATUSES.includes(value));
148
+ }
149
+ function exactObject(properties) {
150
+ return {
151
+ type: "object",
152
+ properties,
153
+ required: Object.keys(properties),
154
+ additionalProperties: false,
155
+ };
156
+ }
157
+ function boundedText(maxLength) {
158
+ return { type: "string", minLength: 1, maxLength };
159
+ }
160
+ function enumString(values) {
161
+ const uniqueValues = [...new Set(values)];
162
+ return {
163
+ type: "string",
164
+ enum: uniqueValues.length > 0 ? uniqueValues : ["__none__"],
165
+ };
166
+ }
167
+ function exactKeys(record, keys, path, issues) {
168
+ const expected = new Set(keys);
169
+ const actual = Object.keys(record);
170
+ if (actual.length !== expected.size ||
171
+ actual.some((key) => !expected.has(key))) {
172
+ issues.push(issue("reviewer_audit_shape_invalid", path));
173
+ }
174
+ }
175
+ function asRecord(value) {
176
+ return value !== null && typeof value === "object" && !Array.isArray(value)
177
+ ? value
178
+ : undefined;
179
+ }
180
+ function issue(code, path) {
181
+ return {
182
+ code,
183
+ path,
184
+ message: `Reviewer audit failed ${code}.`,
185
+ };
186
+ }
@@ -1,4 +1,4 @@
1
- import { type RoleCapabilityResultReference, type RoleCallFrame } from "../../orchestration/role-calls/index.js";
1
+ import { type RoleCapabilityResultReference, type RoleCallFrame, type RoleCallReviewerVerdictGap } from "../../orchestration/role-calls/index.js";
2
2
  export declare const REVIEWER_DECISION_MODEL_STEP: "reviewer.decision";
3
3
  export declare const REVIEWER_ROLE_ID: "reviewer";
4
4
  export declare const REVIEWER_DECISION_ACTIONS: readonly ["pass", "report_gaps"];
@@ -17,6 +17,7 @@ export declare const REVIEWER_EVIDENCE_REFERENCE_DATA_MAX_LENGTH = 32768;
17
17
  export declare const REVIEWER_DECISION_SUMMARY_MAX_LENGTH = 256;
18
18
  export declare const REVIEWER_GAP_SUMMARY_MAX_LENGTH = 224;
19
19
  export declare const REVIEWER_DECISION_RESULT_MAX_LENGTH = 8192;
20
+ export declare function resolveCanonicalReviewerCompletionTargetText(source: string): string;
20
21
  export type ReviewerFactStatus = "satisfied" | "missing" | "mismatched" | "contradictory" | "indeterminate" | "informational";
21
22
  export type ReviewerEvidenceOutcome = "succeeded" | "failed";
22
23
  export type ReviewerEvidenceEffect = "none" | "observation" | "mutation" | "indeterminate";
@@ -56,13 +57,7 @@ export type ReviewerReviewSnapshot = Readonly<{
56
57
  facts: readonly ReviewerFact[];
57
58
  evidence: readonly ReviewerEvidence[];
58
59
  }>;
59
- export type ReviewerGap = Readonly<{
60
- kind: string;
61
- subjectRefs: readonly string[];
62
- factRefs: readonly string[];
63
- evidenceRefs: readonly string[];
64
- summary: string;
65
- }>;
60
+ export type ReviewerGap = RoleCallReviewerVerdictGap;
66
61
  export type ReviewerPassDecision = Readonly<{
67
62
  action: "pass";
68
63
  reviewScopeId: string;
@@ -1,5 +1,5 @@
1
1
  import { MODEL_STEPS } from "../../../shared/model-steps.js";
2
- import { ROLE_CALL_OBJECTIVE_MAX_LENGTH, ROLE_CAPABILITY_REFERENCE_DATA_MAX_LENGTH, ROLE_CALL_RESULT_MAX_LENGTH, } from "../../orchestration/role-calls/index.js";
2
+ import { ROLE_CALL_OBJECTIVE_MAX_LENGTH, ROLE_CAPABILITY_REFERENCE_DATA_MAX_LENGTH, ROLE_CALL_RESULT_MAX_LENGTH, ROLE_CALL_REVIEWER_VERDICT_GAP_SUMMARY_MAX_LENGTH, ROLE_CALL_REVIEWER_VERDICT_KIND_MAX_LENGTH, ROLE_CALL_REVIEWER_VERDICT_MAX_GAPS, ROLE_CALL_REVIEWER_VERDICT_MAX_REFS_PER_GAP, ROLE_CALL_REVIEWER_VERDICT_REFERENCE_MAX_LENGTH, } from "../../orchestration/role-calls/index.js";
3
3
  export const REVIEWER_DECISION_MODEL_STEP = MODEL_STEPS.REVIEWER_DECISION;
4
4
  export const REVIEWER_ROLE_ID = "reviewer";
5
5
  export const REVIEWER_DECISION_ACTIONS = Object.freeze([
@@ -9,18 +9,24 @@ export const REVIEWER_DECISION_ACTIONS = Object.freeze([
9
9
  export const REVIEWER_MAX_SUBJECTS = 64;
10
10
  export const REVIEWER_MAX_FACTS = 64;
11
11
  export const REVIEWER_MAX_EVIDENCE = 64;
12
- export const REVIEWER_MAX_GAPS = 5;
12
+ export const REVIEWER_MAX_GAPS = ROLE_CALL_REVIEWER_VERDICT_MAX_GAPS;
13
13
  export const REVIEWER_MAX_GAP_KINDS = 64;
14
- export const REVIEWER_MAX_REFS_PER_GAP = 1;
14
+ export const REVIEWER_MAX_REFS_PER_GAP = ROLE_CALL_REVIEWER_VERDICT_MAX_REFS_PER_GAP;
15
15
  export const REVIEWER_MAX_SNAPSHOT_LINK_REFS = 64;
16
- export const REVIEWER_REFERENCE_MAX_LENGTH = 256;
17
- export const REVIEWER_KIND_MAX_LENGTH = 160;
16
+ export const REVIEWER_REFERENCE_MAX_LENGTH = ROLE_CALL_REVIEWER_VERDICT_REFERENCE_MAX_LENGTH;
17
+ export const REVIEWER_KIND_MAX_LENGTH = ROLE_CALL_REVIEWER_VERDICT_KIND_MAX_LENGTH;
18
18
  export const REVIEWER_ITEM_SUMMARY_MAX_LENGTH = 2_048;
19
19
  export const REVIEWER_COMPLETION_TARGET_MAX_LENGTH = ROLE_CALL_OBJECTIVE_MAX_LENGTH;
20
20
  export const REVIEWER_EVIDENCE_REFERENCE_DATA_MAX_LENGTH = ROLE_CAPABILITY_REFERENCE_DATA_MAX_LENGTH;
21
21
  export const REVIEWER_DECISION_SUMMARY_MAX_LENGTH = 256;
22
- export const REVIEWER_GAP_SUMMARY_MAX_LENGTH = 224;
22
+ export const REVIEWER_GAP_SUMMARY_MAX_LENGTH = ROLE_CALL_REVIEWER_VERDICT_GAP_SUMMARY_MAX_LENGTH;
23
23
  export const REVIEWER_DECISION_RESULT_MAX_LENGTH = ROLE_CALL_RESULT_MAX_LENGTH;
24
+ export function resolveCanonicalReviewerCompletionTargetText(source) {
25
+ const normalized = source.trim();
26
+ if (!normalized)
27
+ throw new Error("reviewer_completion_target_missing");
28
+ return normalized.slice(0, REVIEWER_COMPLETION_TARGET_MAX_LENGTH);
29
+ }
24
30
  export function projectReviewerDecisionCallIdentity(call) {
25
31
  if (call.roleId !== REVIEWER_ROLE_ID ||
26
32
  call.parentCallId === null ||
@@ -0,0 +1,24 @@
1
+ import { type RoleCallFrame, type RoleCallLedgerHead } from "../../orchestration/role-calls/index.js";
2
+ import { type ReviewerFact, type ReviewerSubject } from "./contracts.js";
3
+ export type ReviewerDelegatedContextProjection = Readonly<{
4
+ subjects: readonly ReviewerSubject[];
5
+ facts: readonly ReviewerFact[];
6
+ subjectBindings: readonly Readonly<{
7
+ callId: string;
8
+ subjectRef: string;
9
+ }>[];
10
+ scopedTopLevelCallIds: readonly string[];
11
+ excludedReviewerCallIds: readonly string[];
12
+ projectionComplete: boolean;
13
+ }>;
14
+ /**
15
+ * Projects only the exact canonical dependency results attached to the active
16
+ * Reviewer call. The projection describes prior work without granting it
17
+ * user-intent, routing, verdict, or completion authority.
18
+ */
19
+ export declare function projectReviewerDelegatedContext(params: Readonly<{
20
+ head: RoleCallLedgerHead;
21
+ reviewer: RoleCallFrame;
22
+ subjectCapacity: number;
23
+ factCapacity: number;
24
+ }>): ReviewerDelegatedContextProjection;
@@ -0,0 +1,70 @@
1
+ import { projectRoleCallDependencyResults, } from "../../orchestration/role-calls/index.js";
2
+ import { REVIEWER_ITEM_SUMMARY_MAX_LENGTH, } from "./contracts.js";
3
+ /**
4
+ * Projects only the exact canonical dependency results attached to the active
5
+ * Reviewer call. The projection describes prior work without granting it
6
+ * user-intent, routing, verdict, or completion authority.
7
+ */
8
+ export function projectReviewerDelegatedContext(params) {
9
+ const dependencies = projectRoleCallDependencyResults(params.head, params.reviewer);
10
+ const subjects = [];
11
+ const facts = [];
12
+ const subjectBindings = [];
13
+ const scopedTopLevelCallIds = [];
14
+ const excludedReviewerCallIds = [];
15
+ let projectionComplete = true;
16
+ for (const dependency of dependencies) {
17
+ const producer = params.head.state.calls.find(({ callId }) => callId === dependency.producerCallId);
18
+ if (!producer)
19
+ throw new Error("reviewer_dependency_producer_missing");
20
+ scopedTopLevelCallIds.push(producer.callId);
21
+ if (producer.roleId === "reviewer") {
22
+ excludedReviewerCallIds.push(producer.callId);
23
+ }
24
+ const subjectRef = `call:${producer.callId}`;
25
+ const objective = producer.objective ?? `${producer.roleId} work`;
26
+ projectionComplete =
27
+ !isSummaryTruncated(objective) && projectionComplete;
28
+ if (subjects.length >= params.subjectCapacity) {
29
+ projectionComplete = false;
30
+ continue;
31
+ }
32
+ subjects.push({
33
+ subjectRef,
34
+ kind: `${producer.roleId}_result`,
35
+ summary: boundedSummary(objective),
36
+ });
37
+ subjectBindings.push({ callId: producer.callId, subjectRef });
38
+ projectionComplete =
39
+ !isSummaryTruncated(dependency.summary) && projectionComplete;
40
+ if (facts.length >= params.factCapacity) {
41
+ projectionComplete = false;
42
+ continue;
43
+ }
44
+ facts.push({
45
+ factRef: dependency.resultRef,
46
+ kind: "role_result",
47
+ status: dependency.outcome === "completed" ? "informational" : "missing",
48
+ subjectRefs: Object.freeze([subjectRef]),
49
+ evidenceRefs: Object.freeze([]),
50
+ summary: boundedSummary(dependency.summary),
51
+ });
52
+ }
53
+ return Object.freeze({
54
+ subjects: Object.freeze(subjects),
55
+ facts: Object.freeze(facts),
56
+ subjectBindings: Object.freeze(subjectBindings),
57
+ scopedTopLevelCallIds: Object.freeze(scopedTopLevelCallIds),
58
+ excludedReviewerCallIds: Object.freeze(excludedReviewerCallIds),
59
+ projectionComplete,
60
+ });
61
+ }
62
+ function boundedSummary(value) {
63
+ const normalized = value.trim();
64
+ return normalized.length <= REVIEWER_ITEM_SUMMARY_MAX_LENGTH
65
+ ? normalized
66
+ : normalized.slice(0, REVIEWER_ITEM_SUMMARY_MAX_LENGTH);
67
+ }
68
+ function isSummaryTruncated(value) {
69
+ return value.trim().length > REVIEWER_ITEM_SUMMARY_MAX_LENGTH;
70
+ }
@@ -13,7 +13,7 @@ export function traceReviewerContextProjected(params) {
13
13
  historyMessageCount: 0,
14
14
  attachmentCount: 0,
15
15
  referenceMessageCount: params.referenceMessageCount,
16
- modelContextContract: "runtime_reviewer_audit_v2",
16
+ modelContextContract: "runtime_reviewer_audit_v4",
17
17
  auditCapsuleCharacterCount: params.auditCapsuleCharacterCount,
18
18
  evidenceAppendixCharacterCount: params.evidenceAppendixCharacterCount,
19
19
  continuationMessageCount: 0,
@@ -1,10 +1,18 @@
1
- import { createStructuredDecisionEnvelopeSchema, structuredDecisionVariantSchemaPath, } from "../../model/structured-decision-envelope.js";
1
+ import { createStructuredDecisionEnvelopeSchema, } from "../../model/structured-decision-envelope.js";
2
+ import { createReviewerAuditCoverageSchema } from "./audit-coverage.js";
3
+ import { projectReviewerVerificationCoverage } from "./verification-coverage.js";
2
4
  import { REVIEWER_DECISION_SUMMARY_MAX_LENGTH, REVIEWER_GAP_SUMMARY_MAX_LENGTH, REVIEWER_MAX_GAPS, REVIEWER_MAX_REFS_PER_GAP, } from "./contracts.js";
3
5
  export function createReviewerDecisionFormat(snapshot) {
4
- const passAllowed = snapshot.projectionComplete && snapshot.freshness !== "unavailable";
6
+ const verificationCoverage = projectReviewerVerificationCoverage(snapshot);
7
+ const passAllowed = snapshot.projectionComplete &&
8
+ snapshot.freshness !== "unavailable" &&
9
+ verificationCoverage.complete;
5
10
  const passVariant = exactObject({
6
11
  action: literal("pass"),
7
12
  reviewScopeId: literal(snapshot.reviewScopeId),
13
+ audit: createReviewerAuditCoverageSchema(snapshot, {
14
+ minimumCompletionEvidenceRefs: Math.min(2, snapshot.evidence.length),
15
+ }),
8
16
  summary: boundedText(REVIEWER_DECISION_SUMMARY_MAX_LENGTH),
9
17
  gaps: {
10
18
  type: "array",
@@ -15,10 +23,13 @@ export function createReviewerDecisionFormat(snapshot) {
15
23
  enum: ["__none__"],
16
24
  },
17
25
  },
18
- }, ["action", "reviewScopeId", "summary", "gaps"]);
26
+ }, ["action", "reviewScopeId", "audit", "summary", "gaps"]);
19
27
  const reportGapsVariant = exactObject({
20
28
  action: literal("report_gaps"),
21
29
  reviewScopeId: literal(snapshot.reviewScopeId),
30
+ audit: createReviewerAuditCoverageSchema(snapshot, {
31
+ minimumCompletionEvidenceRefs: 0,
32
+ }),
22
33
  summary: boundedText(REVIEWER_DECISION_SUMMARY_MAX_LENGTH),
23
34
  gaps: {
24
35
  type: "array",
@@ -32,34 +43,17 @@ export function createReviewerDecisionFormat(snapshot) {
32
43
  summary: boundedText(REVIEWER_GAP_SUMMARY_MAX_LENGTH),
33
44
  }, ["kind", "subjectRefs", "factRefs", "evidenceRefs", "summary"]),
34
45
  },
35
- }, ["action", "reviewScopeId", "summary", "gaps"]);
46
+ }, ["action", "reviewScopeId", "audit", "summary", "gaps"]);
36
47
  const variants = passAllowed
37
48
  ? [passVariant, reportGapsVariant]
38
49
  : [reportGapsVariant];
39
- const reportGapsIndex = passAllowed ? 1 : 0;
50
+ const schema = createStructuredDecisionEnvelopeSchema(variants);
40
51
  return {
41
52
  type: "json_schema",
42
53
  name: "reviewer_decision",
43
54
  strict: true,
44
- postValidatedSchemaConstraints: [
45
- ...(passAllowed
46
- ? [
47
- {
48
- keyword: "maxLength",
49
- path: `${structuredDecisionVariantSchemaPath(0, variants.length)}/properties/summary/maxLength`,
50
- },
51
- ]
52
- : []),
53
- {
54
- keyword: "maxLength",
55
- path: `${structuredDecisionVariantSchemaPath(reportGapsIndex, variants.length)}/properties/summary/maxLength`,
56
- },
57
- {
58
- keyword: "maxLength",
59
- path: `${structuredDecisionVariantSchemaPath(reportGapsIndex, variants.length)}/properties/gaps/items/properties/summary/maxLength`,
60
- },
61
- ],
62
- schema: createStructuredDecisionEnvelopeSchema(variants),
55
+ postValidatedSchemaConstraints: collectMaxLengths(schema),
56
+ schema,
63
57
  };
64
58
  }
65
59
  function referenceArray(values) {
@@ -95,3 +89,22 @@ function boundedText(maxLength) {
95
89
  maxLength,
96
90
  };
97
91
  }
92
+ function collectMaxLengths(value, path = "") {
93
+ if (Array.isArray(value)) {
94
+ return value.flatMap((entry, index) => collectMaxLengths(entry, `${path}/${index}`));
95
+ }
96
+ if (!isRecord(value))
97
+ return [];
98
+ return [
99
+ ...(Object.hasOwn(value, "maxLength")
100
+ ? [{ keyword: "maxLength", path: `${path}/maxLength` }]
101
+ : []),
102
+ ...Object.entries(value).flatMap(([key, child]) => collectMaxLengths(child, `${path}/${escapePointer(key)}`)),
103
+ ];
104
+ }
105
+ function escapePointer(value) {
106
+ return value.replace(/~/gu, "~0").replace(/\//gu, "~1");
107
+ }
108
+ function isRecord(value) {
109
+ return value !== null && typeof value === "object" && !Array.isArray(value);
110
+ }
@@ -97,7 +97,7 @@ export function assessReviewerDecisionInputBudget(request, options) {
97
97
  }
98
98
  function createReviewerDecisionInputParts(request, options) {
99
99
  const format = createReviewerDecisionFormat(options.snapshot);
100
- const modelContext = projectReviewerModelContext(options.snapshot);
100
+ const modelContext = projectReviewerModelContext(options.snapshot, options.call);
101
101
  const configuredInstructionMetadata = resolveConfiguredStepInstructionMetadata({
102
102
  runnerConfig: request.runnerConfig,
103
103
  modelStep: REVIEWER_DECISION_MODEL_STEP,
@@ -1,6 +1,7 @@
1
1
  import type { ChatMessage } from "../../../model-gateway/types.js";
2
- import type { ReviewerReviewSnapshot } from "./contracts.js";
3
- export declare const REVIEWER_AUDIT_CONTEXT_KIND: "runtime_reviewer_audit_v2";
2
+ import type { RoleCallFrame } from "../../orchestration/role-calls/index.js";
3
+ import { type ReviewerReviewSnapshot } from "./contracts.js";
4
+ export declare const REVIEWER_AUDIT_CONTEXT_KIND: "runtime_reviewer_audit_v4";
4
5
  export declare const REVIEWER_EVIDENCE_APPENDIX_KIND: "runtime_reviewer_evidence_v1";
5
6
  export type ReviewerModelContextProjection = Readonly<{
6
7
  referenceMessages: readonly ChatMessage[];
@@ -14,4 +15,4 @@ export type ReviewerModelContextProjection = Readonly<{
14
15
  * Large evidence bodies are pinned before the final compact audit capsule so
15
16
  * they remain available without displacing the completion target from recency.
16
17
  */
17
- export declare function projectReviewerModelContext(snapshot: ReviewerReviewSnapshot): ReviewerModelContextProjection;
18
+ export declare function projectReviewerModelContext(snapshot: ReviewerReviewSnapshot, reviewerCall: RoleCallFrame): ReviewerModelContextProjection;
@@ -1,4 +1,6 @@
1
- export const REVIEWER_AUDIT_CONTEXT_KIND = "runtime_reviewer_audit_v2";
1
+ import { projectReviewerDecisionCallIdentity, } from "./contracts.js";
2
+ import { projectReviewerVerificationCoverage } from "./verification-coverage.js";
3
+ export const REVIEWER_AUDIT_CONTEXT_KIND = "runtime_reviewer_audit_v4";
2
4
  export const REVIEWER_EVIDENCE_APPENDIX_KIND = "runtime_reviewer_evidence_v1";
3
5
  const REVIEWER_CANDIDATE_SUPPORT_RELATION = "candidate_support";
4
6
  /**
@@ -6,15 +8,63 @@ const REVIEWER_CANDIDATE_SUPPORT_RELATION = "candidate_support";
6
8
  * Large evidence bodies are pinned before the final compact audit capsule so
7
9
  * they remain available without displacing the completion target from recency.
8
10
  */
9
- export function projectReviewerModelContext(snapshot) {
11
+ export function projectReviewerModelContext(snapshot, reviewerCall) {
12
+ const reviewerIdentity = projectReviewerDecisionCallIdentity(reviewerCall);
13
+ if (reviewerIdentity.callId !== snapshot.reviewerCallId ||
14
+ reviewerIdentity.parentCallId !== snapshot.callerCallId) {
15
+ throw new Error("reviewer_assignment_binding_invalid");
16
+ }
10
17
  const completionTargets = snapshot.subjects.filter(({ kind }) => kind === "caller_objective");
11
18
  if (completionTargets.length !== 1) {
12
19
  throw new Error("reviewer_completion_target_invalid");
13
20
  }
14
21
  const completionTarget = completionTargets[0];
22
+ const verificationCoverage = projectReviewerVerificationCoverage(snapshot);
23
+ const dependencyFactsBySubjectRef = projectDependencyFactsBySubjectRef(snapshot);
24
+ const dependencySubjects = snapshot.subjects.flatMap((subject) => {
25
+ const dependencyFact = dependencyFactsBySubjectRef.get(subject.subjectRef);
26
+ if (!dependencyFact)
27
+ return [];
28
+ const producerCallId = subject.subjectRef.startsWith("call:")
29
+ ? subject.subjectRef.slice("call:".length)
30
+ : "";
31
+ const roleId = subject.kind.endsWith("_result")
32
+ ? subject.kind.slice(0, -"_result".length)
33
+ : "";
34
+ if (!producerCallId || !roleId) {
35
+ throw new Error("reviewer_dependency_subject_invalid");
36
+ }
37
+ return [
38
+ {
39
+ authority: "canonical_role_call_dependency_result",
40
+ presenceEffect: "passive_support_not_user_intent_pending_work_completion_or_verdict",
41
+ subjectRef: subject.subjectRef,
42
+ resultRef: dependencyFact.factRef,
43
+ producerCallId,
44
+ roleId,
45
+ objective: subject.summary,
46
+ summary: dependencyFact.summary,
47
+ outcome: dependencyFact.status === "informational" ? "completed" : "failed",
48
+ },
49
+ ];
50
+ });
51
+ const supportSubjects = snapshot.subjects.flatMap((subject) => subject.subjectRef === completionTarget.subjectRef ||
52
+ dependencyFactsBySubjectRef.has(subject.subjectRef)
53
+ ? []
54
+ : [
55
+ {
56
+ authority: "canonical_review_snapshot",
57
+ presenceEffect: "passive_support_descriptor_not_user_intent_pending_work_or_completion",
58
+ subjectRef: subject.subjectRef,
59
+ kind: subject.kind,
60
+ summary: subject.summary,
61
+ },
62
+ ]);
15
63
  const candidateSupportSubjectRefs = new Set([...snapshot.facts, ...snapshot.evidence].flatMap(({ subjectRefs }) => subjectRefs));
64
+ const passiveReviewerDependencySubjectRefs = new Set(dependencySubjects.flatMap(({ roleId, subjectRef }) => roleId === "reviewer" ? [subjectRef] : []));
16
65
  const candidateSupportEdges = snapshot.subjects.flatMap((subject) => subject.subjectRef !== completionTarget.subjectRef &&
17
- candidateSupportSubjectRefs.has(subject.subjectRef)
66
+ candidateSupportSubjectRefs.has(subject.subjectRef) &&
67
+ !passiveReviewerDependencySubjectRefs.has(subject.subjectRef)
18
68
  ? [
19
69
  {
20
70
  sourceSubjectRef: subject.subjectRef,
@@ -44,13 +94,17 @@ export function projectReviewerModelContext(snapshot) {
44
94
  }),
45
95
  ]
46
96
  : []);
47
- const claims = snapshot.facts.map((item) => ({
48
- claimRef: item.factRef,
49
- status: item.status,
50
- summary: item.summary,
51
- subjectRefs: item.subjectRefs,
52
- evidenceRefs: item.evidenceRefs,
53
- }));
97
+ const claims = snapshot.facts.flatMap((item) => item.kind === "role_result"
98
+ ? []
99
+ : [
100
+ {
101
+ claimRef: item.factRef,
102
+ status: item.status,
103
+ summary: item.summary,
104
+ subjectRefs: item.subjectRefs,
105
+ evidenceRefs: item.evidenceRefs,
106
+ },
107
+ ]);
54
108
  const effects = snapshot.evidence.map((item) => ({
55
109
  evidenceRef: item.evidenceRef,
56
110
  outcome: item.outcome,
@@ -70,6 +124,20 @@ export function projectReviewerModelContext(snapshot) {
70
124
  ? "current_revision"
71
125
  : snapshot.freshness,
72
126
  },
127
+ verificationCoverage: {
128
+ authority: "runtime_projection",
129
+ presenceEffect: "pass_eligibility_only_not_semantic_completion_proof_or_user_intent",
130
+ ...verificationCoverage,
131
+ },
132
+ assignment: {
133
+ authority: "canonical_reviewer_call",
134
+ callId: reviewerIdentity.callId,
135
+ purpose: "audit_supplied_completion_target",
136
+ presenceEffect: "active_reviewer_assignment_only",
137
+ completionTargetRef: completionTarget.subjectRef,
138
+ },
139
+ dependencySubjects,
140
+ supportSubjects,
73
141
  candidateSupportPolicy: {
74
142
  authority: "runtime_projection",
75
143
  sourceClaimsAndEffectsMaySupportTarget: true,
@@ -93,3 +161,17 @@ export function projectReviewerModelContext(snapshot) {
93
161
  evidenceAppendixCharacterCount: referenceMessages.reduce((total, message) => total + message.content.length, 0),
94
162
  });
95
163
  }
164
+ function projectDependencyFactsBySubjectRef(snapshot) {
165
+ const projected = new Map();
166
+ for (const fact of snapshot.facts) {
167
+ if (fact.kind !== "role_result")
168
+ continue;
169
+ if (fact.subjectRefs.length !== 1 ||
170
+ (fact.status !== "informational" && fact.status !== "missing") ||
171
+ projected.has(fact.subjectRefs[0])) {
172
+ throw new Error("reviewer_dependency_fact_invalid");
173
+ }
174
+ projected.set(fact.subjectRefs[0], fact);
175
+ }
176
+ return projected;
177
+ }