@markstanden/opencode-test-container 0.0.0-stage → 0.1.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 (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +263 -2
  3. package/container/Containerfile +24 -0
  4. package/container/README.md +29 -0
  5. package/dist/adapters/opencode/events.d.ts +90 -0
  6. package/dist/adapters/opencode/events.js +213 -0
  7. package/dist/adapters/opencode/runtime.d.ts +87 -0
  8. package/dist/adapters/opencode/runtime.js +136 -0
  9. package/dist/adapters/podman/container.d.ts +62 -0
  10. package/dist/adapters/podman/container.js +119 -0
  11. package/dist/adapters/podman/image.d.ts +50 -0
  12. package/dist/adapters/podman/image.js +124 -0
  13. package/dist/adapters/process.d.ts +38 -0
  14. package/dist/adapters/process.js +71 -0
  15. package/dist/campaign/assess.d.ts +45 -0
  16. package/dist/campaign/assess.js +208 -0
  17. package/dist/campaign/close.d.ts +17 -0
  18. package/dist/campaign/close.js +112 -0
  19. package/dist/campaign/evidence-guard.d.ts +24 -0
  20. package/dist/campaign/evidence-guard.js +49 -0
  21. package/dist/campaign/freeze.d.ts +94 -0
  22. package/dist/campaign/freeze.js +297 -0
  23. package/dist/campaign/inventory.d.ts +62 -0
  24. package/dist/campaign/inventory.js +192 -0
  25. package/dist/campaign/judge.d.ts +209 -0
  26. package/dist/campaign/judge.js +1285 -0
  27. package/dist/campaign/ledger.d.ts +64 -0
  28. package/dist/campaign/ledger.js +149 -0
  29. package/dist/campaign/prepare.d.ts +129 -0
  30. package/dist/campaign/prepare.js +483 -0
  31. package/dist/campaign/primary.d.ts +96 -0
  32. package/dist/campaign/primary.js +189 -0
  33. package/dist/campaign/run.d.ts +151 -0
  34. package/dist/campaign/run.js +562 -0
  35. package/dist/campaign/status.d.ts +76 -0
  36. package/dist/campaign/status.js +237 -0
  37. package/dist/cli/otc.d.ts +51 -0
  38. package/dist/cli/otc.js +435 -0
  39. package/dist/contracts/canonical.d.ts +21 -0
  40. package/dist/contracts/canonical.js +44 -0
  41. package/dist/contracts/types.d.ts +261 -0
  42. package/dist/contracts/types.js +9 -0
  43. package/dist/contracts/validate.d.ts +72 -0
  44. package/dist/contracts/validate.js +1021 -0
  45. package/dist/contracts/version.d.ts +44 -0
  46. package/dist/contracts/version.js +147 -0
  47. package/dist/evaluators/docs/analysis/accounting.d.ts +140 -0
  48. package/dist/evaluators/docs/analysis/accounting.js +237 -0
  49. package/dist/evaluators/docs/analysis/blinding.d.ts +40 -0
  50. package/dist/evaluators/docs/analysis/blinding.js +80 -0
  51. package/dist/evaluators/docs/analysis/bounds.d.ts +40 -0
  52. package/dist/evaluators/docs/analysis/bounds.js +31 -0
  53. package/dist/evaluators/docs/analysis/budget.d.ts +137 -0
  54. package/dist/evaluators/docs/analysis/budget.js +305 -0
  55. package/dist/evaluators/docs/analysis/closure.d.ts +175 -0
  56. package/dist/evaluators/docs/analysis/closure.js +251 -0
  57. package/dist/evaluators/docs/analysis/decision.d.ts +59 -0
  58. package/dist/evaluators/docs/analysis/decision.js +161 -0
  59. package/dist/evaluators/docs/analysis/freeze.d.ts +201 -0
  60. package/dist/evaluators/docs/analysis/freeze.js +395 -0
  61. package/dist/evaluators/docs/analysis/guardrails.d.ts +51 -0
  62. package/dist/evaluators/docs/analysis/guardrails.js +194 -0
  63. package/dist/evaluators/docs/analysis/journal.d.ts +150 -0
  64. package/dist/evaluators/docs/analysis/journal.js +475 -0
  65. package/dist/evaluators/docs/analysis/ledger.d.ts +78 -0
  66. package/dist/evaluators/docs/analysis/ledger.js +145 -0
  67. package/dist/evaluators/docs/analysis/measures.d.ts +302 -0
  68. package/dist/evaluators/docs/analysis/measures.js +1069 -0
  69. package/dist/evaluators/docs/analysis/model.d.ts +236 -0
  70. package/dist/evaluators/docs/analysis/model.js +740 -0
  71. package/dist/evaluators/docs/analysis/pairing.d.ts +68 -0
  72. package/dist/evaluators/docs/analysis/pairing.js +95 -0
  73. package/dist/evaluators/docs/analysis/records.d.ts +229 -0
  74. package/dist/evaluators/docs/analysis/records.js +935 -0
  75. package/dist/evaluators/docs/analysis/recovery.d.ts +225 -0
  76. package/dist/evaluators/docs/analysis/recovery.js +507 -0
  77. package/dist/evaluators/docs/analysis/render.d.ts +235 -0
  78. package/dist/evaluators/docs/analysis/render.js +566 -0
  79. package/dist/evaluators/docs/analysis/replay.d.ts +15 -0
  80. package/dist/evaluators/docs/analysis/replay.js +1272 -0
  81. package/dist/evaluators/docs/analysis/screening/inventory.d.ts +136 -0
  82. package/dist/evaluators/docs/analysis/screening/inventory.js +307 -0
  83. package/dist/evaluators/docs/analysis/screening/noteVersion.d.ts +15 -0
  84. package/dist/evaluators/docs/analysis/screening/noteVersion.js +46 -0
  85. package/dist/evaluators/docs/analysis/screening/reconcile.d.ts +38 -0
  86. package/dist/evaluators/docs/analysis/screening/reconcile.js +40 -0
  87. package/dist/evaluators/docs/analysis/screening/rules.d.ts +163 -0
  88. package/dist/evaluators/docs/analysis/screening/rules.js +330 -0
  89. package/dist/evaluators/docs/analysis/screening/scan.d.ts +72 -0
  90. package/dist/evaluators/docs/analysis/screening/scan.js +362 -0
  91. package/dist/evaluators/docs/analysis/selector.d.ts +68 -0
  92. package/dist/evaluators/docs/analysis/selector.js +123 -0
  93. package/dist/evaluators/docs/assess.d.ts +129 -0
  94. package/dist/evaluators/docs/assess.js +433 -0
  95. package/dist/evaluators/docs/campaign.d.ts +133 -0
  96. package/dist/evaluators/docs/campaign.js +222 -0
  97. package/dist/evaluators/docs/index.d.ts +25 -0
  98. package/dist/evaluators/docs/index.js +25 -0
  99. package/dist/evaluators/docs/journal.d.ts +150 -0
  100. package/dist/evaluators/docs/journal.js +475 -0
  101. package/dist/evaluators/docs/scoring.d.ts +367 -0
  102. package/dist/evaluators/docs/scoring.js +662 -0
  103. package/dist/evaluators/skills/assess.d.ts +94 -0
  104. package/dist/evaluators/skills/assess.js +207 -0
  105. package/dist/index.d.ts +46 -0
  106. package/dist/index.js +29 -0
  107. package/dist/legacy/prod014.d.ts +86 -0
  108. package/dist/legacy/prod014.js +209 -0
  109. package/dist/reporting/report.d.ts +79 -0
  110. package/dist/reporting/report.js +242 -0
  111. package/docs/architecture.md +106 -0
  112. package/docs/capability-matrix.md +84 -0
  113. package/docs/offline-rehearsal.md +75 -0
  114. package/docs/parity-record.md +81 -0
  115. package/docs/pr-description.md +103 -0
  116. package/docs/schema.md +97 -0
  117. package/examples/skills/README.md +13 -0
  118. package/examples/skills/campaign.json +73 -0
  119. package/examples/skills/skills/otel-helper/SKILL.md +10 -0
  120. package/examples/skills/suite.json +29 -0
  121. package/package.json +45 -5
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Campaign-level structured scoring for automatic-notetaking trials.
3
+ *
4
+ * The harness's semantic judge answers a case rubric and its deterministic
5
+ * gate answers "was a required write made". A prose comparison needs a
6
+ * third, separate measure: one mutually exclusive documentation outcome per
7
+ * trial, scored by declared utility weights, plus the independent
8
+ * primary-task result. This module is the pure part — prompt construction,
9
+ * strict parsing/validation against the mutation evidence, scoring,
10
+ * sensitivity and the frozen selection rule — so a campaign cannot silently
11
+ * turn a malformed judge answer or a note in a restraint case into a pass.
12
+ *
13
+ * Nothing here calls a model or touches the filesystem.
14
+ */
15
+ /** The one documentation outcome a trial receives. */
16
+ export type DocumentationOutcome = "useful-create" | "useful-update" | "transient" | "duplicate" | "misleading" | "none";
17
+ /** The scenario whose correction needs a semantic preservation assessment. */
18
+ export declare const PRESERVATION_CASE = "R02";
19
+ /** The assessed state of one still-valid fact. */
20
+ export type PreservationState = "retained" | "corrected" | "lost";
21
+ /** The assessed state of the superseded TLS claim. */
22
+ export type ObsoleteClaimState = "removed" | "retained";
23
+ /** One fact's evidence-backed preservation finding. */
24
+ export interface PreservationFinding {
25
+ /** Whether the fact survived, was corrected, or was lost. */
26
+ state: PreservationState;
27
+ /** The decisive excerpt from the after-trial documents. */
28
+ quote: string;
29
+ }
30
+ /** The required R02 preservation assessment, one entry per fixed fact. */
31
+ export interface PreservationAssessment {
32
+ /** The 10-connection pool cap. */
33
+ poolSize: PreservationFinding;
34
+ /** The 5-second acquire timeout. */
35
+ acquireTimeout: PreservationFinding;
36
+ /** Startup migrations. */
37
+ startupMigrations: PreservationFinding;
38
+ /** The obsolete `sslmode=disable` claim. */
39
+ obsoleteTlsClaim: {
40
+ state: ObsoleteClaimState;
41
+ quote: string;
42
+ };
43
+ }
44
+ /** One configured fact in a scenario-keyed preservation inventory. */
45
+ export interface PreservationFactSpec {
46
+ /** Stable fact id, used as the judgement field name. */
47
+ id: string;
48
+ /** Human-readable label for the prompt. */
49
+ label: string;
50
+ /** True when the fact is the superseded claim rather than a still-valid one. */
51
+ obsolete?: boolean;
52
+ }
53
+ /** A scenario-keyed preservation inventory the judge must assess. */
54
+ export interface PreservationSpec {
55
+ /** The facts to assess, in prompt order. */
56
+ facts: PreservationFactSpec[];
57
+ }
58
+ /** The seeded note and distinctive detail a retrieval assessment is about. */
59
+ export interface RetrievalSpec {
60
+ /** Lake-relative path of the seeded note. */
61
+ note: string;
62
+ /** The declared lake holding the note, when the declaration names one. */
63
+ lake?: string;
64
+ /** The actionable detail the task must apply. */
65
+ detail: string;
66
+ }
67
+ /** The assessed state of a trial's use of a seeded note. */
68
+ export type RetrievalState = "applied" | "read-not-applied" | "search-only" | "not-retrieved" | "unknown";
69
+ /** One trial's retrieval-application finding. */
70
+ export interface RetrievalApplication {
71
+ /** Whether the note was retrieved and applied, read only, searched only, etc. */
72
+ state: RetrievalState;
73
+ /** The decisive excerpt, or "(none)". */
74
+ quote: string;
75
+ }
76
+ /** Everything a judge must state about one trial's documentation. */
77
+ export interface AcJudgement {
78
+ /** The one outcome the trial earns. */
79
+ documentationOutcome: DocumentationOutcome;
80
+ /** Why that outcome, naming every mixed component. */
81
+ documentationReason: string;
82
+ /** Decisive excerpts from the resulting documents/evidence. */
83
+ evidence: string[];
84
+ /** The R02 preservation assessment, required only for that scenario. */
85
+ preservation?: PreservationAssessment;
86
+ /** The retrieval-application assessment, when the scenario declares one. */
87
+ retrievalApplication?: RetrievalApplication;
88
+ }
89
+ /** The mutation facts the judgement is validated against. */
90
+ export interface DocState {
91
+ /** Whether any file under the documentation surface changed at all. */
92
+ documentsChanged: boolean;
93
+ /** New Markdown document paths under the documentation surface. */
94
+ createdPaths: string[];
95
+ /** Changed pre-existing Markdown document paths. */
96
+ modifiedPaths: string[];
97
+ }
98
+ /** Utility weights, frozen before scored sessions. */
99
+ export interface UtilityWeights {
100
+ /** Reward for a useful create and a useful update. */
101
+ useful: number;
102
+ /** Penalty for a supported but valueless transient note. */
103
+ transient: number;
104
+ /** Penalty for a duplicate note. */
105
+ duplicate: number;
106
+ /** Penalty for misleading or unsupported documentation. */
107
+ misleading: number;
108
+ /** Penalty for a failed primary task. */
109
+ taskFailure: number;
110
+ }
111
+ /** The prospective defaults declared by the campaign prompt. */
112
+ export declare const DEFAULT_WEIGHTS: UtilityWeights;
113
+ /** The one documentation outcome a trial receives. */
114
+ export declare const DOCUMENTATION_OUTCOMES: readonly DocumentationOutcome[];
115
+ /** One trial's resolved inputs for scoring. */
116
+ export interface ScoredTrial {
117
+ /** The arm the trial belongs to. */
118
+ arm: string;
119
+ /** The scenario it ran. */
120
+ scenario: string;
121
+ /** Whether the trial was planned (a slot in the frozen schedule). */
122
+ planned: boolean;
123
+ /** Whether the session completed with usable evidence. */
124
+ usable: boolean;
125
+ /** The documentation outcome, absent when not assessed. */
126
+ outcome?: DocumentationOutcome | undefined;
127
+ /** The independent primary-check result. */
128
+ primary: "pass" | "fail" | "unknown";
129
+ /** A non-compensable guardrail breach (unauthorised/destructive write). */
130
+ guardrailBreach: boolean;
131
+ }
132
+ /**
133
+ * Build the arm-blind judge prompt for one trial.
134
+ *
135
+ * Every input is arm-neutral by construction: the task the agent was given,
136
+ * the standing permission, the authoring truth for the scenario, the
137
+ * knowledge-lake documents before and after, the changed paths, the
138
+ * independent primary-check result, the observed docs operations and the
139
+ * final answer. No arm label, candidate description, hypothesis, prior
140
+ * verdict or aggregate result is accepted by this function.
141
+ * @param input The labelled evidence blocks.
142
+ * @param input.taskPrompt The exact task the agent was given.
143
+ * @param input.standingPermission The workspace permission file's contents.
144
+ * @param input.scenarioTruth The scenario's durable-finding facts.
145
+ * @param input.beforeDocs Knowledge-lake documents before the trial.
146
+ * @param input.afterDocs Knowledge-lake documents after the trial.
147
+ * @param input.changedPaths Paths the trial changed.
148
+ * @param input.primary The independent primary-check result.
149
+ * @param input.primary.status The checker's status.
150
+ * @param input.primary.exit Its exit code, or null.
151
+ * @param input.primary.stdout Its captured stdout.
152
+ * @param input.primary.stderr Its captured stderr.
153
+ * @param input.docsOperations Verified docs operations observed.
154
+ * @param input.answer The trial's final answer.
155
+ * @param input.requirePreservation Require the R02 semantic preservation block.
156
+ * @param input.preservationSpec A scenario-keyed preservation inventory.
157
+ * @param input.retrievalSpec A seeded-note retrieval-application assessment.
158
+ * @returns The complete judge prompt.
159
+ */
160
+ export declare function buildAcPrompt(input: {
161
+ taskPrompt: string;
162
+ standingPermission: string;
163
+ scenarioTruth: string;
164
+ beforeDocs: Array<{
165
+ path: string;
166
+ contents: string;
167
+ }>;
168
+ afterDocs: Array<{
169
+ path: string;
170
+ contents: string;
171
+ }>;
172
+ changedPaths: string[];
173
+ primary: {
174
+ status: string;
175
+ exit: number | null;
176
+ stdout: string;
177
+ stderr: string;
178
+ };
179
+ docsOperations: string[];
180
+ answer: string;
181
+ requirePreservation?: boolean;
182
+ preservationSpec?: PreservationSpec;
183
+ retrievalSpec?: RetrievalSpec;
184
+ }): string;
185
+ /** Pull the one JSON object out of a judge's prose, if any. */
186
+ export declare function parseAcJudgement(text: string): {
187
+ value?: Record<string, unknown>;
188
+ problems: string[];
189
+ };
190
+ /**
191
+ * The machine-readable reason one judge attempt produced no usable verdict.
192
+ *
193
+ * A complete-but-malformed answer (`json-syntax`, `schema`, `semantic`) is a
194
+ * model-output failure; `empty-or-truncated` means the capture itself cannot
195
+ * establish a final assessed response, so it is never eligible for a
196
+ * registered recovery. `transport-or-process` is assigned by the caller that
197
+ * observed the process exit.
198
+ */
199
+ export type JudgeFailureClass = "transport-or-process" | "empty-or-truncated" | "json-syntax" | "schema" | "semantic";
200
+ /**
201
+ * Classify a non-usable parsed answer.
202
+ *
203
+ * Completion refers to the final assessed response: the caller must establish
204
+ * that the trail terminated on the final text part and that the text is
205
+ * nonblank. When completion cannot be established the class is
206
+ * `empty-or-truncated` regardless of the parse failure, because a recovery
207
+ * must never be dispatched against unknown capture.
208
+ * @param input The recorded facts and problems.
209
+ * @param input.complete Whether the capture proves a complete final response.
210
+ * @param input.value The parsed value, absent on a parse failure.
211
+ * @param input.problems The recorded problems.
212
+ * @returns The failure class.
213
+ */
214
+ export declare function judgeFailureClass(input: {
215
+ complete: boolean;
216
+ value?: Record<string, unknown> | undefined;
217
+ problems: string[];
218
+ }): Exclude<JudgeFailureClass, "transport-or-process">;
219
+ /** Schema problems for one parsed judgement: fields, enums and evidence. */
220
+ export declare function judgementSchemaProblems(value: Record<string, unknown>): string[];
221
+ /** Allowed states for a retrieval-application finding. */
222
+ export declare const RETRIEVAL_STATES: readonly RetrievalState[];
223
+ /**
224
+ * Check a parsed judgement against its schema AND the recorded mutation
225
+ * evidence. A judgement that contradicts the evidence is invalid, never
226
+ * silently corrected: "none" with a changed document, or a create with no
227
+ * created document, means the judge did not read the evidence.
228
+ * @param value The parsed judge object.
229
+ * @param state The mutation facts for the trial.
230
+ * @param options Preservation and retrieval requirements.
231
+ * @param options.requirePreservation True for the R02 correction scenario.
232
+ * @param options.preservationSpec A scenario-keyed preservation inventory.
233
+ * @param options.retrieval True when the scenario needs a retrieval finding.
234
+ * @returns The problems; empty means a usable judgement.
235
+ */
236
+ export declare function validateAcJudgement(value: Record<string, unknown>, state: DocState, options?: {
237
+ requirePreservation?: boolean;
238
+ preservationSpec?: PreservationSpec;
239
+ retrieval?: boolean;
240
+ }): string[];
241
+ /** The documentation component of one trial's utility. */
242
+ export declare function documentationScore(outcome: DocumentationOutcome, weights?: UtilityWeights): number;
243
+ /**
244
+ * The closed documentation interval for an unassessed outcome: the lowest and
245
+ * highest score any allowed outcome can earn under the declared weights.
246
+ * Derived from the policy, never assumed — a custom duplicate penalty can sit
247
+ * below the misleading penalty, and the interval must follow it.
248
+ * @param weights The frozen utility weights.
249
+ * @returns The lowest and highest possible documentation scores.
250
+ */
251
+ export declare function documentationRange(weights?: UtilityWeights): {
252
+ low: number;
253
+ high: number;
254
+ };
255
+ /**
256
+ * One trial's utility, or a closed interval when a component is unknown.
257
+ *
258
+ * An unassessed documentation outcome contributes nothing and is reported as
259
+ * missing, never as zero. The documentation interval is the full range of
260
+ * allowed outcome scores under the declared weights; the task interval
261
+ * retains whatever the primary check already established, so a known pass
262
+ * does not widen the bound as though it too were unknown.
263
+ */
264
+ export declare function trialUtility(trial: ScoredTrial, weights?: UtilityWeights): {
265
+ score: number;
266
+ low: number;
267
+ high: number;
268
+ assessed: boolean;
269
+ };
270
+ /** Per-arm aggregate of the frozen trial population. */
271
+ export interface ArmSummary {
272
+ /** The arm this summary describes. */
273
+ arm: string;
274
+ /** Planned slots. */
275
+ planned: number;
276
+ /** Slots whose session started. */
277
+ attempted: number;
278
+ /** Slots that completed. */
279
+ completed: number;
280
+ /** Slots with usable evidence. */
281
+ usable: number;
282
+ /** Slots with a usable documentation judgement. */
283
+ assessed: number;
284
+ /** Count of trials per documentation outcome. */
285
+ outcomes: Record<DocumentationOutcome, number>;
286
+ /** Primary checks that passed. */
287
+ primaryPass: number;
288
+ /** Primary checks that failed. */
289
+ primaryFail: number;
290
+ /** Primary checks without a usable result. */
291
+ primaryUnknown: number;
292
+ /** Trials flagged for a non-compensable guardrail breach. */
293
+ guardrailBreaches: number;
294
+ /** Sum of assessed trial utilities. */
295
+ total: number;
296
+ /** Mean over planned slots, or null without a denominator. */
297
+ meanPerPlanned: number | null;
298
+ /** Mean over assessed slots, or null without a denominator. */
299
+ meanPerAssessed: number | null;
300
+ /** Sum of the low bounds of every unassessed planned trial. */
301
+ missingLow: number;
302
+ /** Sum of the high bounds of every unassessed planned trial. */
303
+ missingHigh: number;
304
+ }
305
+ /**
306
+ * Aggregate one arm's trials. Means are reported per planned trial (the
307
+ * pre-registered denominator, with missing trials visible in the bounds) and
308
+ * per assessed trial separately, so an incomplete arm cannot hide behind a
309
+ * smaller denominator.
310
+ * @param trials The arm's planned slots.
311
+ * @param weights The frozen utility weights.
312
+ * @returns The arm summary.
313
+ */
314
+ export declare function summariseArm(trials: ScoredTrial[], weights?: UtilityWeights): ArmSummary;
315
+ /**
316
+ * The frozen finalist rule: a candidate qualifies only with complete
317
+ * assessments for both arms, no guardrail breach, and a default-utility lead
318
+ * of at least the threshold across the compared trials.
319
+ * @param control The control arm summary.
320
+ * @param candidate The candidate arm summary.
321
+ * @param threshold The required lead.
322
+ * @returns Whether the candidate qualifies, and why not when it does not.
323
+ */
324
+ export declare function finalistQualifies(control: ArmSummary, candidate: ArmSummary, threshold: number): {
325
+ qualifies: boolean;
326
+ reason: string;
327
+ };
328
+ /**
329
+ * Rank the eligible candidates by the frozen order: default utility, then
330
+ * fewer primary-task failures, then fewer misleading outcomes, then fewer
331
+ * description characters, then arm id.
332
+ * @param candidates The candidate summaries with their description lengths.
333
+ * @returns The same list, best first.
334
+ */
335
+ export declare function rankCandidates(candidates: Array<{
336
+ summary: ArmSummary;
337
+ characters: number;
338
+ arm: string;
339
+ }>): Array<{
340
+ summary: ArmSummary;
341
+ characters: number;
342
+ arm: string;
343
+ }>;
344
+ /** One sensitivity cell: useful weight × transient penalty. */
345
+ export interface SensitivityCell {
346
+ /** The useful create/update weight in this cell. */
347
+ useful: number;
348
+ /** The transient penalty (positive magnitude) in this cell. */
349
+ transient: number;
350
+ /** Total utility per arm. */
351
+ totals: Record<string, number>;
352
+ /** Arms best first. */
353
+ ranking: string[];
354
+ }
355
+ /**
356
+ * Re-score every arm under the requested weight grid, holding the other
357
+ * penalties fixed at the campaign's declared weights. This explores
358
+ * preferences; it is not nine experiments.
359
+ * @param arms The planned trials, keyed by arm.
360
+ * @param usefulWeights The useful create/update rewards to try.
361
+ * @param transientPenalties The transient penalties to try, as positive
362
+ * magnitudes applied as negative scores.
363
+ * @param baseWeights The campaign's non-grid weights; defaults to the
364
+ * prospective defaults so legacy callers keep their frozen baseline.
365
+ * @returns One cell per combination, with totals and the resulting ranking.
366
+ */
367
+ export declare function sensitivity(arms: Record<string, ScoredTrial[]>, usefulWeights: number[], transientPenalties: number[], baseWeights?: UtilityWeights): SensitivityCell[];