modelrig 0.11.0 → 0.12.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 (199) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/adapters/anthropic.d.ts +4 -4
  3. package/dist/adapters/anthropic.d.ts.map +1 -1
  4. package/dist/adapters/anthropic.js +8 -1
  5. package/dist/adapters/deepseek.d.ts +2 -4
  6. package/dist/adapters/deepseek.d.ts.map +1 -1
  7. package/dist/adapters/deepseek.js +9 -5
  8. package/dist/adapters/gemini.d.ts +4 -1
  9. package/dist/adapters/gemini.d.ts.map +1 -1
  10. package/dist/adapters/gemini.js +16 -1
  11. package/dist/adapters/grok.d.ts +2 -4
  12. package/dist/adapters/grok.d.ts.map +1 -1
  13. package/dist/adapters/grok.js +8 -4
  14. package/dist/adapters/history-mapping.d.ts +126 -0
  15. package/dist/adapters/history-mapping.d.ts.map +1 -0
  16. package/dist/adapters/history-mapping.js +230 -0
  17. package/dist/adapters/openai-compat.d.ts +2 -4
  18. package/dist/adapters/openai-compat.d.ts.map +1 -1
  19. package/dist/adapters/openai-compat.js +9 -5
  20. package/dist/adapters/openai.d.ts +2 -4
  21. package/dist/adapters/openai.d.ts.map +1 -1
  22. package/dist/adapters/openai.js +8 -4
  23. package/dist/adapters/responses-api.d.ts.map +1 -1
  24. package/dist/adapters/responses-api.js +9 -4
  25. package/dist/artifacts/artifact.d.ts.map +1 -1
  26. package/dist/artifacts/artifact.js +79 -0
  27. package/dist/artifacts/conversation.d.ts +128 -0
  28. package/dist/artifacts/conversation.d.ts.map +1 -0
  29. package/dist/artifacts/conversation.js +172 -0
  30. package/dist/artifacts/index.d.ts +1 -1
  31. package/dist/artifacts/index.d.ts.map +1 -1
  32. package/dist/artifacts/media.d.ts +46 -0
  33. package/dist/artifacts/media.d.ts.map +1 -0
  34. package/dist/artifacts/media.js +88 -0
  35. package/dist/artifacts/run-context.d.ts +61 -2
  36. package/dist/artifacts/run-context.d.ts.map +1 -1
  37. package/dist/artifacts/run-context.js +183 -12
  38. package/dist/artifacts/scrub.d.ts +3 -0
  39. package/dist/artifacts/scrub.d.ts.map +1 -1
  40. package/dist/bakeoff/engine.d.ts.map +1 -1
  41. package/dist/bakeoff/engine.js +34 -7
  42. package/dist/bakeoff/eval-cases.d.ts +5 -0
  43. package/dist/bakeoff/eval-cases.d.ts.map +1 -1
  44. package/dist/bakeoff/eval-cases.js +10 -1
  45. package/dist/bakeoff/replay.d.ts +15 -0
  46. package/dist/bakeoff/replay.d.ts.map +1 -1
  47. package/dist/bakeoff/replay.js +19 -1
  48. package/dist/bakeoff/report.d.ts.map +1 -1
  49. package/dist/bakeoff/report.js +9 -2
  50. package/dist/bakeoff/turn-replay.d.ts +93 -0
  51. package/dist/bakeoff/turn-replay.d.ts.map +1 -0
  52. package/dist/bakeoff/turn-replay.js +150 -0
  53. package/dist/bakeoff/types.d.ts +12 -0
  54. package/dist/bakeoff/types.d.ts.map +1 -1
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +1 -0
  57. package/dist/config.d.ts +18 -0
  58. package/dist/config.d.ts.map +1 -1
  59. package/dist/config.js +23 -3
  60. package/dist/doctor-preflight.d.ts.map +1 -1
  61. package/dist/doctor-preflight.js +6 -1
  62. package/dist/feedback/grade.d.ts +7 -2
  63. package/dist/feedback/grade.d.ts.map +1 -1
  64. package/dist/feedback/grade.js +14 -0
  65. package/dist/feedback/outcome.d.ts +103 -0
  66. package/dist/feedback/outcome.d.ts.map +1 -0
  67. package/dist/feedback/outcome.js +175 -0
  68. package/dist/gateway/history-bridge.d.ts +32 -0
  69. package/dist/gateway/history-bridge.d.ts.map +1 -0
  70. package/dist/gateway/history-bridge.js +64 -0
  71. package/dist/gateway/serve-client.d.ts.map +1 -1
  72. package/dist/gateway/serve-client.js +6 -0
  73. package/dist/index.d.ts +44 -1
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +110 -9
  76. package/dist/init/init-cli.d.ts.map +1 -1
  77. package/dist/init/init-cli.js +21 -4
  78. package/dist/init/observe-cli.js +1 -1
  79. package/dist/init/observe.d.ts +7 -1
  80. package/dist/init/observe.d.ts.map +1 -1
  81. package/dist/init/observe.js +74 -22
  82. package/dist/init/starter.d.ts +36 -0
  83. package/dist/init/starter.d.ts.map +1 -0
  84. package/dist/init/starter.js +85 -0
  85. package/dist/registry/build.d.ts +4 -0
  86. package/dist/registry/build.d.ts.map +1 -1
  87. package/dist/registry/generation-models.d.ts +68 -0
  88. package/dist/registry/generation-models.d.ts.map +1 -0
  89. package/dist/registry/generation-models.js +168 -0
  90. package/dist/registry/model-kind.d.ts +34 -0
  91. package/dist/registry/model-kind.d.ts.map +1 -0
  92. package/dist/registry/model-kind.js +40 -0
  93. package/dist/registry/pricing-shape.d.ts +29 -1
  94. package/dist/registry/pricing-shape.d.ts.map +1 -1
  95. package/dist/registry/pricing-shape.js +9 -0
  96. package/dist/registry/pricing.d.ts +26 -0
  97. package/dist/registry/pricing.d.ts.map +1 -1
  98. package/dist/registry/pricing.js +29 -0
  99. package/dist/registry/rows.d.ts.map +1 -1
  100. package/dist/registry/rows.js +3 -1
  101. package/dist/registry/unit-pricing.d.ts +32 -0
  102. package/dist/registry/unit-pricing.d.ts.map +1 -0
  103. package/dist/registry/unit-pricing.js +62 -0
  104. package/dist/routes/input-loader.d.ts +38 -0
  105. package/dist/routes/input-loader.d.ts.map +1 -0
  106. package/dist/routes/input-loader.js +80 -0
  107. package/dist/routes/loader.d.ts.map +1 -1
  108. package/dist/routes/loader.js +3 -0
  109. package/dist/routes/resolved-bundle.d.ts +2 -0
  110. package/dist/routes/resolved-bundle.d.ts.map +1 -1
  111. package/dist/routes/resolved-bundle.js +3 -0
  112. package/dist/run/cost.d.ts +28 -0
  113. package/dist/run/cost.d.ts.map +1 -1
  114. package/dist/run/cost.js +74 -0
  115. package/dist/run/dispatch.d.ts +4 -1
  116. package/dist/run/dispatch.d.ts.map +1 -1
  117. package/dist/run/dispatch.js +3 -0
  118. package/dist/run/limits.d.ts +88 -0
  119. package/dist/run/limits.d.ts.map +1 -0
  120. package/dist/run/limits.js +155 -0
  121. package/dist/run/messages.d.ts +199 -0
  122. package/dist/run/messages.d.ts.map +1 -0
  123. package/dist/run/messages.js +430 -0
  124. package/dist/run/raw-finalize.d.ts +5 -2
  125. package/dist/run/raw-finalize.d.ts.map +1 -1
  126. package/dist/run/raw-finalize.js +8 -5
  127. package/dist/run/raw-request.d.ts.map +1 -1
  128. package/dist/run/raw-request.js +2 -1
  129. package/dist/run/raw.d.ts +10 -4
  130. package/dist/run/raw.d.ts.map +1 -1
  131. package/dist/run/raw.js +11 -3
  132. package/dist/run/rawonly.d.ts +29 -5
  133. package/dist/run/rawonly.d.ts.map +1 -1
  134. package/dist/run/rawonly.js +54 -19
  135. package/dist/run/record-attempt.d.ts.map +1 -1
  136. package/dist/run/record-attempt.js +16 -6
  137. package/dist/run/record-call.d.ts +13 -2
  138. package/dist/run/record-call.d.ts.map +1 -1
  139. package/dist/run/record-call.js +50 -7
  140. package/dist/run/run.d.ts.map +1 -1
  141. package/dist/run/run.js +12 -8
  142. package/dist/telemetry/attempt-meta.d.ts +49 -1
  143. package/dist/telemetry/attempt-meta.d.ts.map +1 -1
  144. package/dist/telemetry/attempt-meta.js +45 -1
  145. package/dist/telemetry/exporter.d.ts.map +1 -1
  146. package/dist/telemetry/exporter.js +2 -1
  147. package/dist/telemetry/grade-mappers.d.ts +1 -1
  148. package/dist/telemetry/grade-mappers.d.ts.map +1 -1
  149. package/dist/telemetry/grade-mappers.js +7 -1
  150. package/dist/telemetry/grade-task.d.ts +49 -0
  151. package/dist/telemetry/grade-task.d.ts.map +1 -0
  152. package/dist/telemetry/grade-task.js +85 -0
  153. package/dist/telemetry/grades-sql.d.ts +16 -1
  154. package/dist/telemetry/grades-sql.d.ts.map +1 -1
  155. package/dist/telemetry/grades-sql.js +64 -4
  156. package/dist/telemetry/ingest-protocol.d.ts +24 -1
  157. package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
  158. package/dist/telemetry/ingest-protocol.js +72 -43
  159. package/dist/telemetry/otel-content.d.ts +31 -0
  160. package/dist/telemetry/otel-content.d.ts.map +1 -0
  161. package/dist/telemetry/otel-content.js +106 -0
  162. package/dist/telemetry/otel-hierarchy.d.ts +57 -0
  163. package/dist/telemetry/otel-hierarchy.d.ts.map +1 -0
  164. package/dist/telemetry/otel-hierarchy.js +155 -0
  165. package/dist/telemetry/otel-normalize.d.ts +15 -1
  166. package/dist/telemetry/otel-normalize.d.ts.map +1 -1
  167. package/dist/telemetry/otel-normalize.js +24 -39
  168. package/dist/telemetry/sinks.d.ts +4 -1
  169. package/dist/telemetry/sinks.d.ts.map +1 -1
  170. package/dist/telemetry/sinks.js +53 -34
  171. package/dist/telemetry/store-migrations.d.ts.map +1 -1
  172. package/dist/telemetry/store-migrations.js +8 -0
  173. package/dist/telemetry/store.d.ts +9 -0
  174. package/dist/telemetry/store.d.ts.map +1 -1
  175. package/dist/telemetry/store.js +10 -0
  176. package/dist/telemetry/uniform-rows.d.ts +43 -0
  177. package/dist/telemetry/uniform-rows.d.ts.map +1 -0
  178. package/dist/telemetry/uniform-rows.js +139 -0
  179. package/dist/types/failures-teaching.d.ts.map +1 -1
  180. package/dist/types/failures-teaching.js +11 -0
  181. package/dist/types/failures.d.ts +1 -1
  182. package/dist/types/failures.d.ts.map +1 -1
  183. package/dist/types/failures.js +2 -0
  184. package/dist/types/provider.d.ts +12 -0
  185. package/dist/types/provider.d.ts.map +1 -1
  186. package/dist/types/route.d.ts +13 -0
  187. package/dist/types/route.d.ts.map +1 -1
  188. package/dist/types/telemetry.d.ts +14 -1
  189. package/dist/types/telemetry.d.ts.map +1 -1
  190. package/docs/agent-skill/SKILL.md +122 -12
  191. package/docs/how-it-fits.md +4 -4
  192. package/docs/instrumentation.md +148 -44
  193. package/docs/llms.txt +143 -13
  194. package/docs/mcp-oracle.md +15 -4
  195. package/docs/quickstart.md +129 -16
  196. package/package.json +4 -2
  197. package/registry/registry.json +456 -0
  198. package/templates/creative-approval.json +81 -0
  199. package/templates/support-conversation.json +82 -0
@@ -12,6 +12,7 @@ exports.formatDisagreementSummary = formatDisagreementSummary;
12
12
  exports.formatSwapDirection = formatSwapDirection;
13
13
  exports.printMatrix = printMatrix;
14
14
  exports.runEvalCaseBakeoffCli = runEvalCaseBakeoffCli;
15
+ const turn_replay_1 = require("./turn-replay");
15
16
  const node_fs_1 = require("node:fs");
16
17
  const node_os_1 = require("node:os");
17
18
  const node_path_1 = require("node:path");
@@ -75,7 +76,7 @@ function bakeoffHeadline(artifact) {
75
76
  : "cost n/a";
76
77
  const ceiling = fmtCeiling(artifact);
77
78
  const r = p.regret;
78
- return (`${p.variant} — regret ${fmtPts(r.regretMean)} pts ` +
79
+ return (`${p.variant}${arm?.armLabel !== undefined ? ` (${arm.armLabel})` : ""} — regret ${fmtPts(r.regretMean)} pts ` +
79
80
  `(CI ${fmtPts(r.regretCi95[0])}…${fmtPts(r.regretCi95[1])}, n=${r.nPaired}) vs reference ${ref.model}, ` +
80
81
  `${cost}${ceiling !== null ? ` vs ceiling ${ceiling}` : ""} — proposed`);
81
82
  }
@@ -178,7 +179,7 @@ function printMatrix(artifact, cacheAdjusted = []) {
178
179
  header.push("pairwise-win");
179
180
  const rows = artifact.variants.map((m) => {
180
181
  const base = [
181
- m.isReference === true ? `${m.variant} [ref]` : m.variant,
182
+ m.isReference === true ? `${m.variant} [ref]` : m.armLabel !== undefined ? `${m.variant} (${m.armLabel})` : m.variant, // ARC-β R3-1
182
183
  String(m.samples),
183
184
  `${(m.conformRate * 100).toFixed(0)}%`,
184
185
  `[${(m.conformCi95[0] * 100).toFixed(0)},${(m.conformCi95[1] * 100).toFixed(0)}]`,
@@ -225,6 +226,12 @@ function printMatrix(artifact, cacheAdjusted = []) {
225
226
  // byte-identical to the pre-N6 matrix output.
226
227
  for (const l of formatDisagreementSummary(artifact))
227
228
  console.log(l);
229
+ for (const m of artifact.variants)
230
+ for (const l of (0, turn_replay_1.formatIncomparable)(m.incomparable ?? []))
231
+ console.log(`[${m.variant}] ${l}`); // ARC-β M3(c)
232
+ for (const m of artifact.variants)
233
+ for (const l of (0, turn_replay_1.formatFallbackServed)(m.servedByFallback ?? []))
234
+ console.log(`[${m.variant}] ${l}`); // ARC-β R3-1
228
235
  // Cache-adjusted section (spec §5.4) — printed only when the caller supplied
229
236
  // simulator rows; absent ⇒ the matrix output is byte-identical to pre-WS-B.
230
237
  for (const l of formatCacheAdjustedSection(cacheAdjusted))
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Turn replay — ARC-β (agent-archetypes spec §4, builder-prompt-02 §1.7).
3
+ *
4
+ * "Would a cheaper model have answered THIS turn as well, given the same
5
+ * conversation?" A messages route's capture row holds the history up to and
6
+ * including the turn's last user/tool message (run/messages.ts capture codec)
7
+ * and the served reply. The bake-off replays that history against each
8
+ * candidate, which answers the FINAL turn only, graded by the route's existing
9
+ * grader path with the regret bound unchanged. Replay NEVER continues a
10
+ * conversation past the captured turn — there is no simulated next user turn
11
+ * (spec §9 refuses user simulators).
12
+ *
13
+ * M15 GUARD (unruled → conservative, roadmap §2): turn replay re-sends real
14
+ * end-user text to candidate models and graders, so it runs only for routes
15
+ * whose capture is EXPLICITLY on under the existing capture posture
16
+ * (`effectiveCapture`: the control-plane flip wins, else the YAML flag).
17
+ * Otherwise the bake-off refuses with a teaching 422.
18
+ */
19
+ import { RouteConfigError } from "../routes/loader";
20
+ import type { TaskSettingsResolver } from "../settings/task-settings";
21
+ import type { CaptureRow } from "../telemetry/capture";
22
+ import type { RouteBundle } from "../types/route";
23
+ import type { HistoryMessage } from "../run/messages";
24
+ import type { CaptureReplayInput } from "../run/messages";
25
+ import type { RigFailure } from "../types/failures";
26
+ import type { ReplaySampleResult } from "./replay";
27
+ /** The bake-off refused a messages route because capture is not explicitly on.
28
+ * A RouteConfigError (refused before any spend), carrying the HTTP status a
29
+ * server surface should answer with. */
30
+ export declare class TurnReplayRefusedError extends RouteConfigError {
31
+ readonly httpStatus = 422;
32
+ constructor(route: string);
33
+ }
34
+ /** Throw {@link TurnReplayRefusedError} for a messages route whose capture is
35
+ * not explicitly on; a no-op for every variables route (byte-identical). */
36
+ export declare function assertTurnReplayAllowed(route: Pick<RouteBundle, "route" | "inputKind" | "capture">, settings: TaskSettingsResolver | null): void;
37
+ /** One replayable turn of a captured conversation. */
38
+ export interface TurnReplayCase {
39
+ /** The route variables the system template renders from. */
40
+ readonly variables: Record<string, unknown>;
41
+ /** The conversation up to and including the turn's last user/tool message. */
42
+ readonly history: readonly HistoryMessage[];
43
+ /** The reply that was served for this turn (the capture's output). */
44
+ readonly reference: string;
45
+ /** The live call's tools (R2-1), when it declared any. */
46
+ readonly tools?: CaptureReplayInput["tools"];
47
+ readonly toolChoice?: CaptureReplayInput["toolChoice"];
48
+ }
49
+ /** The turn a capture row encodes, or null for a variables (non-messages) row. */
50
+ export declare function turnReplayCase(capture: Pick<CaptureRow, "variablesJson" | "outputText">): TurnReplayCase | null;
51
+ /** The incomparable marker for a replay failure, or null for an ordinary one. */
52
+ export declare function incomparableFrom(failure: RigFailure): {
53
+ readonly model: string;
54
+ readonly reason: string;
55
+ } | null;
56
+ /** One "n cases incomparable for <model>: reason" line's data. */
57
+ export interface IncomparableSummary {
58
+ readonly model: string;
59
+ readonly reason: string;
60
+ readonly n: number;
61
+ }
62
+ /**
63
+ * Split an arm's samples into the COMPARABLE ones (scored, paired for regret)
64
+ * and a per-(model, reason) count of the incomparable ones. An incomparable
65
+ * sample is neither a pass nor a failure: dropping it from both sides of the
66
+ * pairing keeps it from biasing the verdict.
67
+ */
68
+ export declare function splitIncomparable(samples: readonly ReplaySampleResult[]): {
69
+ readonly comparable: readonly ReplaySampleResult[];
70
+ readonly incomparable: readonly IncomparableSummary[];
71
+ };
72
+ /** The report lines: "n cases incomparable for <model>: reason". */
73
+ export declare function formatIncomparable(rows: readonly IncomparableSummary[]): string[];
74
+ /** The `history_skipped` value on a replayed call's telemetry rows, if any. */
75
+ export declare function skippedTagOf(rows: readonly {
76
+ readonly tagsJson: string;
77
+ }[]): string | undefined;
78
+ /** One "n cases served by <servedBy> (<skipped> skipped: <reason>)" row. */
79
+ export interface FallbackServed {
80
+ readonly servedBy: string;
81
+ /** The skipped candidates, `provider/model=code` comma-joined (the tag value). */
82
+ readonly skipped: string;
83
+ readonly n: number;
84
+ }
85
+ /** Count an arm's comparable samples answered by a fallback, grouped by
86
+ * (served model, skipped set). Empty when nothing was skipped. */
87
+ export declare function fallbackServed(samples: readonly ReplaySampleResult[]): FallbackServed[];
88
+ /** "<first> → <fallback…> (fallback served n/N)" — the label an arm's numbers
89
+ * carry when any of its cases was served by a fallback. */
90
+ export declare function fallbackArmLabel(first: string, rows: readonly FallbackServed[], total: number): string;
91
+ /** The report lines for an arm's fallback-served cases. */
92
+ export declare function formatFallbackServed(rows: readonly FallbackServed[]): string[];
93
+ //# sourceMappingURL=turn-replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-replay.d.ts","sourceRoot":"","sources":["../../src/bakeoff/turn-replay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * Turn replay — ARC-β (agent-archetypes spec §4, builder-prompt-02 §1.7).
4
+ *
5
+ * "Would a cheaper model have answered THIS turn as well, given the same
6
+ * conversation?" A messages route's capture row holds the history up to and
7
+ * including the turn's last user/tool message (run/messages.ts capture codec)
8
+ * and the served reply. The bake-off replays that history against each
9
+ * candidate, which answers the FINAL turn only, graded by the route's existing
10
+ * grader path with the regret bound unchanged. Replay NEVER continues a
11
+ * conversation past the captured turn — there is no simulated next user turn
12
+ * (spec §9 refuses user simulators).
13
+ *
14
+ * M15 GUARD (unruled → conservative, roadmap §2): turn replay re-sends real
15
+ * end-user text to candidate models and graders, so it runs only for routes
16
+ * whose capture is EXPLICITLY on under the existing capture posture
17
+ * (`effectiveCapture`: the control-plane flip wins, else the YAML flag).
18
+ * Otherwise the bake-off refuses with a teaching 422.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.TurnReplayRefusedError = void 0;
22
+ exports.assertTurnReplayAllowed = assertTurnReplayAllowed;
23
+ exports.turnReplayCase = turnReplayCase;
24
+ exports.incomparableFrom = incomparableFrom;
25
+ exports.splitIncomparable = splitIncomparable;
26
+ exports.formatIncomparable = formatIncomparable;
27
+ exports.skippedTagOf = skippedTagOf;
28
+ exports.fallbackServed = fallbackServed;
29
+ exports.fallbackArmLabel = fallbackArmLabel;
30
+ exports.formatFallbackServed = formatFallbackServed;
31
+ const loader_1 = require("../routes/loader");
32
+ const task_settings_1 = require("../settings/task-settings");
33
+ const messages_1 = require("../run/messages");
34
+ /** The bake-off refused a messages route because capture is not explicitly on.
35
+ * A RouteConfigError (refused before any spend), carrying the HTTP status a
36
+ * server surface should answer with. */
37
+ class TurnReplayRefusedError extends loader_1.RouteConfigError {
38
+ constructor(route) {
39
+ super(`turn replay refused for route "${route}": it serves conversations (input: messages), and replaying them ` +
40
+ "re-sends end-user text to candidate models — allowed only where capture is explicitly on. Turn capture on " +
41
+ "for this route (`capture: true`, or the console capture flip), let it record real turns, then re-run the " +
42
+ "bake-off (see messages-lane.md#turn-replay)");
43
+ this.httpStatus = 422;
44
+ this.name = "TurnReplayRefusedError";
45
+ }
46
+ }
47
+ exports.TurnReplayRefusedError = TurnReplayRefusedError;
48
+ /** Throw {@link TurnReplayRefusedError} for a messages route whose capture is
49
+ * not explicitly on; a no-op for every variables route (byte-identical). */
50
+ function assertTurnReplayAllowed(route, settings) {
51
+ if (route.inputKind !== "messages")
52
+ return;
53
+ if (!(0, task_settings_1.effectiveCapture)(settings, route.route, route.capture))
54
+ throw new TurnReplayRefusedError(route.route);
55
+ }
56
+ /** The turn a capture row encodes, or null for a variables (non-messages) row. */
57
+ function turnReplayCase(capture) {
58
+ const parsed = (0, messages_1.parseCaptureInput)(capture.variablesJson);
59
+ if (parsed.messages === undefined)
60
+ return null;
61
+ return {
62
+ variables: parsed.input,
63
+ history: parsed.messages,
64
+ reference: capture.outputText,
65
+ ...(parsed.tools !== undefined ? { tools: parsed.tools } : {}),
66
+ ...(parsed.toolChoice !== undefined ? { toolChoice: parsed.toolChoice } : {}),
67
+ };
68
+ }
69
+ // ── Incomparable cases (architect ruling M3(c), 2026-10-24) ──────────────────
70
+ /** The incomparable marker for a replay failure, or null for an ordinary one. */
71
+ function incomparableFrom(failure) {
72
+ if (!failure.message.startsWith(messages_1.HISTORY_INCOMPATIBLE_PREFIX))
73
+ return null;
74
+ const model = failure.provider !== undefined && failure.model !== undefined ? `${failure.provider}/${failure.model}` : "every candidate of the arm";
75
+ return { model, reason: failure.message.slice(messages_1.HISTORY_INCOMPATIBLE_PREFIX.length).replace(/^:\s*/, "") };
76
+ }
77
+ /**
78
+ * Split an arm's samples into the COMPARABLE ones (scored, paired for regret)
79
+ * and a per-(model, reason) count of the incomparable ones. An incomparable
80
+ * sample is neither a pass nor a failure: dropping it from both sides of the
81
+ * pairing keeps it from biasing the verdict.
82
+ */
83
+ function splitIncomparable(samples) {
84
+ const counts = new Map();
85
+ const comparable = [];
86
+ for (const s of samples) {
87
+ if (s.incomparable === undefined) {
88
+ comparable.push(s);
89
+ continue;
90
+ }
91
+ const key = `${s.incomparable.model}\u0000${s.incomparable.reason}`;
92
+ const prev = counts.get(key);
93
+ counts.set(key, { model: s.incomparable.model, reason: s.incomparable.reason, n: (prev?.n ?? 0) + 1 });
94
+ }
95
+ return { comparable, incomparable: [...counts.values()] };
96
+ }
97
+ /** The report lines: "n cases incomparable for <model>: reason". */
98
+ function formatIncomparable(rows) {
99
+ return rows.map((r) => `${r.n} case${r.n === 1 ? "" : "s"} incomparable for ${r.model}: ${r.reason}`);
100
+ }
101
+ // ── Fallback attribution (QA R3-1, 2026-10-24) ────────────────────────────────
102
+ // Under ruling R2-2 a multi-candidate arm whose first candidate cannot take a
103
+ // tool-loop history is served by a later one. The bake-off must say so — an
104
+ // arm's numbers are never presented under a model that never saw the turn.
105
+ /** The `history_skipped` value on a replayed call's telemetry rows, if any. */
106
+ function skippedTagOf(rows) {
107
+ for (const r of rows) {
108
+ try {
109
+ const v = JSON.parse(r.tagsJson)[messages_1.HISTORY_SKIPPED_TAG];
110
+ if (typeof v === "string" && v !== "")
111
+ return v;
112
+ }
113
+ catch {
114
+ // a malformed tags blob carries no skip
115
+ }
116
+ }
117
+ return undefined;
118
+ }
119
+ /** Count an arm's comparable samples answered by a fallback, grouped by
120
+ * (served model, skipped set). Empty when nothing was skipped. */
121
+ function fallbackServed(samples) {
122
+ const counts = new Map();
123
+ for (const s of samples) {
124
+ if (s.historySkipped === undefined || s.servedBy === undefined)
125
+ continue;
126
+ const key = `${s.servedBy}\u0000${s.historySkipped}`;
127
+ counts.set(key, { servedBy: s.servedBy, skipped: s.historySkipped, n: (counts.get(key)?.n ?? 0) + 1 });
128
+ }
129
+ return [...counts.values()];
130
+ }
131
+ /** "<first> → <fallback…> (fallback served n/N)" — the label an arm's numbers
132
+ * carry when any of its cases was served by a fallback. */
133
+ function fallbackArmLabel(first, rows, total) {
134
+ const servedBy = [...new Set(rows.map((r) => r.servedBy))].join(", ");
135
+ const n = rows.reduce((a, r) => a + r.n, 0);
136
+ return `${first} → ${servedBy} (fallback served ${n}/${total})`;
137
+ }
138
+ /** The report lines for an arm's fallback-served cases. */
139
+ function formatFallbackServed(rows) {
140
+ return rows.map((r) => {
141
+ const skipped = r.skipped
142
+ .split(",")
143
+ .map((entry) => {
144
+ const at = entry.lastIndexOf("=");
145
+ return at > 0 ? `${entry.slice(0, at)} skipped: ${entry.slice(at + 1)}` : `${entry} skipped`;
146
+ })
147
+ .join("; ");
148
+ return `${r.n} case${r.n === 1 ? "" : "s"} served by ${r.servedBy} (${skipped})`;
149
+ });
150
+ }
@@ -4,6 +4,7 @@
4
4
  * effective $ per 1K conformant outputs (F1-corrected); RB-1 adds per-sample
5
5
  * value accuracy, paired regret vs a reference arm, and an objective-aware gate.
6
6
  */
7
+ import type { FallbackServed, IncomparableSummary } from "./turn-replay";
7
8
  import type { ObjectiveMode } from "../types/route";
8
9
  import type { PairwiseStats } from "./pairwise";
9
10
  import type { DisagreementReport } from "./disagreement";
@@ -55,6 +56,17 @@ export interface VariantMetrics {
55
56
  * winning variant so the mirror/console read the artifact's decision rather
56
57
  * than recomputing a (mode-blind) winner client-side. */
57
58
  readonly proposed?: boolean;
59
+ /** ARC-β ruling M3(c): captured turns this arm's model could not accept
60
+ * natively — excluded from every number above and from regret; reported as
61
+ * "n cases incomparable for <model>: reason". Absent ⇒ none. */
62
+ readonly incomparable?: readonly IncomparableSummary[];
63
+ /** ARC-β R3-1: cases this arm's ladder answered with a FALLBACK because its
64
+ * earlier candidates were skipped for the history ("n cases served by
65
+ * <provider/model> (<skipped> skipped: <reason>)"). Absent ⇒ none. */
66
+ readonly servedByFallback?: readonly FallbackServed[];
67
+ /** ARC-β R3-1: present with `servedByFallback` — "<first> → <fallback>
68
+ * (fallback served n/N)", the label these numbers must be shown under. */
69
+ readonly armLabel?: string;
58
70
  /** RB-1: this arm's regret vs the reference; null on the reference arm and
59
71
  * when there is no reference. */
60
72
  readonly regret?: RegretStats | null;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bakeoff/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;sEACsE;AACtE,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAE7D;;8CAE8C;AAC9C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,wFAAwF;IACxF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C;;sFAEkF;IAClF,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3D;;sEAEkE;IAClE,QAAQ,CAAC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD;6EACyE;IACzE,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;iFAC6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,iEAAiE;IACjE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,qDAAqD;IACrD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;6DAEyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;qCACiC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,iFAAiF;IACjF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;oCAGgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CAC1C;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;8EAC0E;IAC1E,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C;;8EAE0E;IAC1E,QAAQ,CAAC,QAAQ,EACb;QACE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;QACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;KACtC,GACD,IAAI,CAAC;IACT,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC7C,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC;;;;oBAIgB;IAChB,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C;;;;;qFAKiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;CACjC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bakeoff/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;sEACsE;AACtE,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAE7D;;8CAE8C;AAC9C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,wFAAwF;IACxF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C;;sFAEkF;IAClF,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3D;;sEAEkE;IAClE,QAAQ,CAAC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD;6EACyE;IACzE,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;iFAC6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,iEAAiE;IACjE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,qDAAqD;IACrD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;6DAEyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;oEAEgE;IAChE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACvD;;0EAEsE;IACtE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACtD;8EAC0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;qCACiC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,iFAAiF;IACjF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;oCAGgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CAC1C;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;8EAC0E;IAC1E,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C;;8EAE0E;IAC1E,QAAQ,CAAC,QAAQ,EACb;QACE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;QACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;KACtC,GACD,IAAI,CAAC;IACT,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC7C,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC;;;;oBAIgB;IAChB,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C;;;;;qFAKiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;CACjC"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAsDH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC;AAeD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAuBxD;AA+eD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CnE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAsDH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC;AAeD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAuBxD;AAgfD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CnE"}
package/dist/cli.js CHANGED
@@ -513,6 +513,7 @@ const USAGE = [
513
513
  " modelrig serve (needs the modelrig-server package)",
514
514
  " modelrig bakeoff --route <route> --variants a,b,c --replay-last N [--budget-usd usd] [--objective quality-first|balanced|cost-first] [--keep-outputs[=all]] [--json] [--no-mirror]",
515
515
  " modelrig bakeoff --from-proposal <id> [--replay-last N] [--keep-outputs[=all]] [--json]",
516
+ " modelrig bakeoff --from-eval-cases <task> --variants a,b,c [--budget-usd usd] [--objective quality-first|balanced|cost-first] [--keep-outputs[=all]] [--json] (replays the task's promoted eval cases; no routes dir needed until a case replays)",
516
517
  " modelrig bakeoff --mask-policy <route> [--replay-last N] [--leak-only] (CS-1: masked-vs-unmasked value-accuracy Δ + leak proof; --leak-only = offline, no dispatch)",
517
518
  " modelrig watch run [--events fixtures.json] [--json]",
518
519
  " modelrig regret-monitor --route <route> [--dry-run] [--json] (Q1: one regret-band cycle; files a regret_breach bake-off on breach)",
package/dist/config.d.ts CHANGED
@@ -10,7 +10,14 @@ import type { CapabilityFlag, ProviderId } from "./types/provider";
10
10
  * invariant); `telemetry/attempt-meta.ts:resolvePipelineSha` composes this with
11
11
  * a `.git/HEAD` fallback and never throws. Returns undefined when none is set. */
12
12
  export declare function pipelineShaFromEnv(): string | undefined;
13
+ /** SURF-1 QA: marks a config whose `routesDir` `loadConfigFromEnv` filled in
14
+ * from {@link DEFAULT_ROUTES_DIR} (MODELRIG_ROUTES_DIR unset, no `routesDir`
15
+ * override). The value is the default it filled in. An enumerable symbol key,
16
+ * so it survives `{ ...loadConfigFromEnv(), … }` and never reaches JSON. */
17
+ export declare const ROUTES_DIR_DEFAULTED: unique symbol;
13
18
  export interface RigConfig {
19
+ /** Set by loadConfigFromEnv when it defaulted routesDir (see ROUTES_DIR_DEFAULTED). */
20
+ readonly [ROUTES_DIR_DEFAULTED]?: string;
14
21
  /** Directory of route bundles, OR `null` for a first-class runRaw-only rig
15
22
  * (CE-8, `ce8-runraw-only-rig-spec-plan.md` R1). With `null`, createRig skips
16
23
  * route loading, the `rig.yaml` manifest, and the serveability gate; the raw
@@ -253,6 +260,17 @@ export interface DirectExportConfig extends ExportCommon {
253
260
  * WHICH variable to set rather than "no key configured" (F1 / WS3: errors
254
261
  * that teach). `loadConfigFromEnv` below reads the same names. */
255
262
  export declare const PROVIDER_KEY_ENV: Readonly<Record<string, string>>;
263
+ /** The routes directory `loadConfigFromEnv` uses when MODELRIG_ROUTES_DIR is
264
+ * unset. Exported for createRig's absent-default rule (SURF-1, audit #1). */
265
+ export declare const DEFAULT_ROUTES_DIR = "./modelrig/routes";
266
+ /** True when the config's `routesDir` is the UNCONFIGURED default: it came
267
+ * from `loadConfigFromEnv` filling in {@link DEFAULT_ROUTES_DIR} (env unset, no
268
+ * override) and nobody changed it since. Tracked by where the value came from,
269
+ * not by comparing strings: a `routesDir` you pass in code — even
270
+ * "./modelrig/routes" in a hand-built config — is explicit. createRig treats an
271
+ * absent default dir as "no routes yet" (warn + raw-only) and an explicit absent
272
+ * dir as an error (SURF-1 ruling). */
273
+ export declare function isDefaultRoutesDir(config: RigConfig): boolean;
256
274
  export declare function loadConfigFromEnv(overrides?: Partial<RigConfig>): RigConfig;
257
275
  /**
258
276
  * Narrow `config.export` to DIRECT mode, or explain why the command cannot run.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -5,12 +5,13 @@
5
5
  * __tests__/package-invariants.test.ts).
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.PROVIDER_KEY_ENV = exports.DEFAULT_CONTENT_SCRUB_MODE = void 0;
8
+ exports.DEFAULT_ROUTES_DIR = exports.PROVIDER_KEY_ENV = exports.DEFAULT_CONTENT_SCRUB_MODE = exports.ROUTES_DIR_DEFAULTED = void 0;
9
9
  exports.pipelineShaFromEnv = pipelineShaFromEnv;
10
10
  exports.resolveArtifactsConfig = resolveArtifactsConfig;
11
11
  exports.defaultContentUploadsUrl = defaultContentUploadsUrl;
12
12
  exports.parseOtlpHeaders = parseOtlpHeaders;
13
13
  exports.resolveOtlpConfig = resolveOtlpConfig;
14
+ exports.isDefaultRoutesDir = isDefaultRoutesDir;
14
15
  exports.loadConfigFromEnv = loadConfigFromEnv;
15
16
  exports.directExportOf = directExportOf;
16
17
  const ingest_protocol_1 = require("./telemetry/ingest-protocol");
@@ -27,6 +28,11 @@ function pipelineShaFromEnv() {
27
28
  }
28
29
  return undefined;
29
30
  }
31
+ /** SURF-1 QA: marks a config whose `routesDir` `loadConfigFromEnv` filled in
32
+ * from {@link DEFAULT_ROUTES_DIR} (MODELRIG_ROUTES_DIR unset, no `routesDir`
33
+ * override). The value is the default it filled in. An enumerable symbol key,
34
+ * so it survives `{ ...loadConfigFromEnv(), … }` and never reaches JSON. */
35
+ exports.ROUTES_DIR_DEFAULTED = Symbol.for("modelrig.routesDirDefaulted");
30
36
  /** The scrub mode used when NO control-plane resolver answers for a task
31
37
  * (local-only / direct rigs, or a run with no task identity). The content-on
32
38
  * default — scan and count, upload verbatim. Kept in sync with
@@ -143,7 +149,19 @@ exports.PROVIDER_KEY_ENV = {
143
149
  // not apply to a first-party vendor key).
144
150
  zai: "ZAI_API_KEY",
145
151
  };
146
- const DEFAULT_ROUTES_DIR = "./modelrig/routes";
152
+ /** The routes directory `loadConfigFromEnv` uses when MODELRIG_ROUTES_DIR is
153
+ * unset. Exported for createRig's absent-default rule (SURF-1, audit #1). */
154
+ exports.DEFAULT_ROUTES_DIR = "./modelrig/routes";
155
+ /** True when the config's `routesDir` is the UNCONFIGURED default: it came
156
+ * from `loadConfigFromEnv` filling in {@link DEFAULT_ROUTES_DIR} (env unset, no
157
+ * override) and nobody changed it since. Tracked by where the value came from,
158
+ * not by comparing strings: a `routesDir` you pass in code — even
159
+ * "./modelrig/routes" in a hand-built config — is explicit. createRig treats an
160
+ * absent default dir as "no routes yet" (warn + raw-only) and an explicit absent
161
+ * dir as an error (SURF-1 ruling). */
162
+ function isDefaultRoutesDir(config) {
163
+ return config.routesDir !== null && config[exports.ROUTES_DIR_DEFAULTED] === config.routesDir;
164
+ }
147
165
  const DEFAULT_TELEMETRY_DB = "./.modelrig/telemetry.db";
148
166
  function loadConfigFromEnv(overrides) {
149
167
  const env = process.env;
@@ -204,7 +222,7 @@ function loadConfigFromEnv(overrides) {
204
222
  maxBytes: env.MODELRIG_CONTENT_MAX_BYTES,
205
223
  }, controlPlaneConfigured, devForceOn);
206
224
  const fromEnv = {
207
- routesDir: env.MODELRIG_ROUTES_DIR ?? DEFAULT_ROUTES_DIR,
225
+ routesDir: env.MODELRIG_ROUTES_DIR ?? exports.DEFAULT_ROUTES_DIR,
208
226
  telemetryDbPath: env.MODELRIG_TELEMETRY_DB ?? DEFAULT_TELEMETRY_DB,
209
227
  otlp,
210
228
  artifacts,
@@ -298,10 +316,12 @@ function loadConfigFromEnv(overrides) {
298
316
  return {};
299
317
  })(),
300
318
  };
319
+ const defaulted = env.MODELRIG_ROUTES_DIR === undefined && overrides?.routesDir === undefined;
301
320
  return {
302
321
  ...fromEnv,
303
322
  ...overrides,
304
323
  keys: { ...fromEnv.keys, ...overrides?.keys },
324
+ ...(defaulted ? { [exports.ROUTES_DIR_DEFAULTED]: exports.DEFAULT_ROUTES_DIR } : {}),
305
325
  };
306
326
  }
307
327
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-preflight.d.ts","sourceRoot":"","sources":["../src/doctor-preflight.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;qFACqF;AACrF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/F,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACvF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB;;;;;;4BAMwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,eAAe,GAAG,aAAa,CAAC;IAC5E,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC;iCAC6B;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAIjC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,KAAa;AAC7B;oFACoF;AACpF,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,CAAC,CA4F1B;AAED;iEACiE;AACjE,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,CAMxE;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7F"}
1
+ {"version":3,"file":"doctor-preflight.d.ts","sourceRoot":"","sources":["../src/doctor-preflight.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;qFACqF;AACrF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/F,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACvF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB;;;;;;4BAMwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,eAAe,GAAG,aAAa,CAAC;IAC5E,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC;iCAC6B;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAIjC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,KAAa;AAC7B;oFACoF;AACpF,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,CAAC,CAiG1B;AAED;iEACiE;AACjE,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,CAMxE;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7F"}
@@ -117,7 +117,12 @@ signal) {
117
117
  whoami: who,
118
118
  };
119
119
  }
120
- const orgLabelQuoted = `«${orgLabel}»`;
120
+ // SURF-1 (audit #15): print the slug next to the name — it is what
121
+ // `--expect-org` / `createRig({ expectOrg })` compare, and it was otherwise
122
+ // only in a console tooltip. Omitted when the label already IS the slug.
123
+ const slug = who.org?.slug;
124
+ const slugPart = typeof slug === "string" && slug.trim() !== "" && slug !== orgLabel ? ` (${slug})` : "";
125
+ const orgLabelQuoted = `«${orgLabel}»${slugPart}`;
121
126
  const posture = who.posture?.telemetry;
122
127
  const postureLabel = typeof posture === "string" ? `, telemetry: ${posture}` : "";
123
128
  return {
@@ -11,7 +11,7 @@
11
11
  * (`rig.feedback` / `artifact.evaluate` / `run.evaluate`) and their adapters were
12
12
  * removed in GP-3 — every judgment now builds a grade directly.
13
13
  */
14
- import type { GradeCriterion, GradeRow, GradeSubject } from "../types/telemetry";
14
+ import type { GradeCriterion, GradeKind, GradeRow, GradeSubject } from "../types/telemetry";
15
15
  /** Options for `rig.grade(subject, opts)`. `score` is the 0–1 primitive and is
16
16
  * required; everything else is optional display / provenance. */
17
17
  export interface GradeOpts {
@@ -26,7 +26,9 @@ export interface GradeOpts {
26
26
  };
27
27
  /** Written guidance saved for a later improvement path (was note/explanation). */
28
28
  readonly comment?: string;
29
- readonly kind: "human" | "model-judge" | "deterministic";
29
+ /** `outcome` (ARC-3) is normally written through `rig.outcome`, which derives
30
+ * the subject, `grader = outcome:<name>` and the score for you. */
31
+ readonly kind: GradeKind;
30
32
  /** Optional specific grader name (e.g. "gpt-5-judge", "schema-check"). */
31
33
  readonly grader?: string;
32
34
  /** Provenance (e.g. "sdk", "console", a review-agent name). */
@@ -38,6 +40,9 @@ export interface GradeOpts {
38
40
  * the scrub + dedup/drop-empty-id/clamp guard at persist; this is carried
39
41
  * verbatim. */
40
42
  readonly criteria?: readonly GradeCriterion[];
43
+ /** ARC-3: the raw business value — allowed ONLY on `kind: "outcome"` (a value
44
+ * on any other kind throws: it would be refused server-side). */
45
+ readonly value?: number;
41
46
  /** The grade's own org — server-supplied ONLY, already authorized (T3). Omit
42
47
  * from application code (a rig has one org and the exporter knows it). */
43
48
  readonly orgId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"grade.d.ts","sourceRoot":"","sources":["../../src/feedback/grade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjF;iEACiE;AACjE,MAAM,WAAW,SAAS;IACxB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;6EACyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,eAAe,CAAC;IACzD,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;mBAKe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C;8EAC0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAQD;oFACoF;AACpF,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CA2B9E;AAED;;+DAE+D;AAC/D,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,GAAG;IACzE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;CACzD,CAQA"}
1
+ {"version":3,"file":"grade.d.ts","sourceRoot":"","sources":["../../src/feedback/grade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE5F;iEACiE;AACjE,MAAM,WAAW,SAAS;IACxB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;6EACyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;uEACmE;IACnE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;mBAKe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C;qEACiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;8EAC0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAQD;oFACoF;AACpF,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAoC9E;AAED;;+DAE+D;AAC/D,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,GAAG;IACzE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;CACzD,CAiBA"}
@@ -32,6 +32,11 @@ function buildGradeRow(subject, opts) {
32
32
  if (!Number.isFinite(opts.score) || opts.score < 0 || opts.score > 1) {
33
33
  throw new Error(`grade score must be in [0, 1], got ${opts.score}`);
34
34
  }
35
+ if (opts.value !== undefined && (opts.kind !== "outcome" || !Number.isFinite(opts.value))) {
36
+ throw new Error(opts.kind !== "outcome"
37
+ ? `grade value is only allowed on kind "outcome" (got kind "${opts.kind}") — put the number in score (0–1)`
38
+ : `outcome value must be a finite number, got ${String(opts.value)}`);
39
+ }
35
40
  const { scaleMax, scaleLabel } = scaleFields(opts.scale);
36
41
  return {
37
42
  id: (0, node_crypto_1.randomUUID)(),
@@ -51,6 +56,8 @@ function buildGradeRow(subject, opts) {
51
56
  // a single-score grade's row is byte-identical to pre-F4). Structural
52
57
  // normalization (dedup/clamp/scrub) is the server's job at persist.
53
58
  ...(opts.criteria !== undefined ? { criteria: opts.criteria } : {}),
59
+ // ARC-3: spread-iff so a non-outcome row is byte-identical to pre-ARC.
60
+ ...(opts.value !== undefined ? { value: opts.value } : {}),
54
61
  };
55
62
  }
56
63
  /** Build the rig's `grade` surface over a grade writer (the telemetry store).
@@ -59,6 +66,13 @@ function buildGradeRow(subject, opts) {
59
66
  function makeGradeApi(store) {
60
67
  return {
61
68
  grade(subject, opts) {
69
+ // L4: an outcome is written through rig.outcome (it derives the subject,
70
+ // the outcome:<name> grader, the score and the idempotent id) — a bare
71
+ // rig.grade({ kind: "outcome" }) would be dropped server-side, silently.
72
+ if (opts.kind === "outcome") {
73
+ throw new Error('rig.grade does not record outcomes — use rig.outcome({ key, name, score }) ' +
74
+ "(it files the outcome under outcome:<name> with an idempotent id)");
75
+ }
62
76
  const row = buildGradeRow(subject, opts);
63
77
  store.recordGrade(row);
64
78
  return row;