@basein/runner 0.3.21 → 0.3.22

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 (48) hide show
  1. package/dist/bin/bir-hooks.d.ts +7 -16
  2. package/dist/bin/bir-hooks.js +7 -16
  3. package/dist/bin/bir-scenario.js +1 -1
  4. package/dist/bin/bir.js +1 -21
  5. package/dist/bin/investigate.d.ts +0 -9
  6. package/dist/bin/investigate.js +14 -42
  7. package/dist/bin/scenario-edit.js +13 -44
  8. package/dist/control/recorder-main.d.ts +0 -15
  9. package/dist/control/recorder-main.js +7 -39
  10. package/dist/control/server.d.ts +24 -137
  11. package/dist/control/server.js +101 -995
  12. package/dist/record/recorder.d.ts +11 -142
  13. package/dist/record/recorder.js +0 -3
  14. package/dist/record/remote-recorder.d.ts +1 -9
  15. package/dist/record/remote-recorder.js +3 -49
  16. package/dist/record/switchable-recorder.js +0 -2
  17. package/dist/replay/bundle.d.ts +2 -2
  18. package/dist/replay/bundle.js +3 -3
  19. package/dist/replay/controller.d.ts +19 -123
  20. package/dist/replay/controller.js +151 -518
  21. package/dist/replay/derive.d.ts +0 -10
  22. package/dist/replay/derive.js +0 -3
  23. package/dist/replay/handover.d.ts +2 -37
  24. package/dist/replay/handover.js +38 -106
  25. package/dist/replay/logic.d.ts +0 -11
  26. package/dist/replay/logic.js +0 -24
  27. package/dist/replay/plan.d.ts +43 -163
  28. package/dist/replay/plan.js +144 -556
  29. package/dist/replay/safety.d.ts +4 -5
  30. package/dist/replay/safety.js +7 -7
  31. package/dist/replay/source-run.d.ts +15 -24
  32. package/dist/replay/source-run.js +25 -58
  33. package/dist/replay/targets.d.ts +11 -21
  34. package/dist/replay/targets.js +30 -69
  35. package/dist/replay/types.d.ts +9 -96
  36. package/dist/replay/types.js +3 -16
  37. package/dist/util/service-headers.d.ts +1 -2
  38. package/dist/util/service-headers.js +1 -2
  39. package/docs/calculatedReplay.md +17 -74
  40. package/docs/calculatedReplayGuide.md +9 -30
  41. package/package.json +1 -1
  42. package/production.md +5 -35
  43. package/dist/replay/condition-words.d.ts +0 -28
  44. package/dist/replay/condition-words.js +0 -59
  45. package/dist/replay/flatten.d.ts +0 -161
  46. package/dist/replay/flatten.js +0 -222
  47. package/dist/replay/reads-only.d.ts +0 -29
  48. package/dist/replay/reads-only.js +0 -261
@@ -11,14 +11,13 @@
11
11
  * degrades to "run the turn normally" or returns something the session can
12
12
  * ignore. Nothing throws at a hook.
13
13
  */
14
- import type { ExecutionReport, MatchKey, MatchSegment, MatchVerdict } from "../record/recorder.js";
14
+ import type { ExecutionReport } from "../record/recorder.js";
15
15
  import { type ReplayMode, type StepReach } from "./coverage.js";
16
16
  import { deriveParameters, type AgentDay, type DeriveContext, type DeriveResult } from "./derive.js";
17
17
  import { ProxyWorkQueue } from "./executor.js";
18
18
  import { ScenarioReplayPlan } from "./plan.js";
19
19
  import { type HostSinks } from "./safety.js";
20
20
  import { SourceRunOutputs } from "./source-run.js";
21
- import { type FlatStop } from "./flatten.js";
22
21
  import { type ExecutionOutcome, type ExecutionStepResult, type FallbackKind, type SerializedScenario, type SerializedScenarioStep } from "./types.js";
23
22
  /** The first-party tool a `direct` plan is delivered through (§6.3). */
24
23
  export declare const DIRECT_TOOL_NAME = "mcp__bir__run_scenario";
@@ -239,14 +238,6 @@ export declare const RUN_NO_PLAN = "no_plan";
239
238
  export interface ReplayOptions {
240
239
  /** On unless `BIR_REPLAY=0`. Everything here is inert when false. */
241
240
  enabled: boolean;
242
- /**
243
- * Whether a handed-out segment may run mid-task. The recorder sets it from
244
- * `BIR_SEGMENT_ARM`: on unless that is `0`, from runner 0.3.19 (the
245
- * service's segmentsbreakdown.md SB-21). Omitted, as by a test or an
246
- * embedder, it is off: observe-only, where the runner asks for no segment,
247
- * arms none, and only logs what would have armed (R-OUT-10).
248
- */
249
- segmentArm?: boolean;
250
241
  /** `BIR_REPLAY_ALLOW_SERVERS`; undefined means every wrapped server. */
251
242
  allowServers?: ReadonlySet<string>;
252
243
  /**
@@ -307,21 +298,13 @@ export interface ReplayOptions {
307
298
  export interface IntentMatchOptions {
308
299
  /** `BIR_INTENT_MATCH`. */
309
300
  enabled: boolean;
310
- /**
311
- * How long a `PreToolUse` waits for the service. A timeout is a miss.
312
- *
313
- * 4 000 ms, not the 1 500 of Part 1: a request whose best segment lands in
314
- * the *not clear* band has one live question to ask under the server's own
315
- * 2 500 ms attempt, and must still answer well inside the hook's 30 s
316
- * (segmented.md R-HIT-11). A clear match or a miss answers as fast as before.
317
- */
301
+ /** How long a probe's request may take. A timeout is a miss. */
318
302
  budgetMs: number;
319
303
  /** Plans intent matching may arm in one turn. */
320
304
  maxPerTurn: number;
321
305
  /**
322
- * Probes one turn may *send*. Separate from `maxPerTurn`, and much larger:
323
- * arming three plans is a claim on the turn, while counting hits is only
324
- * bookkeeping, and it must not stop at the third arm (R-HIT-5).
306
+ * Probes one turn may *send*. Separate from `maxPerTurn`, and larger: most
307
+ * probes find nothing, and a turn that armed nothing yet may still match.
325
308
  */
326
309
  maxRequestsPerTurn: number;
327
310
  }
@@ -401,24 +384,10 @@ export interface ReplayState {
401
384
  armedAt: number;
402
385
  reported: boolean;
403
386
  sourceRun?: SourceRunOutputs;
404
- /**
405
- * Why the flattener stopped the plan, when it is what stopped it: a call this
406
- * chain cannot run right now (segmented.md R-CALL-29). The note names the
407
- * sub-task and the reason, and the report carries `unusable_call`.
408
- */
409
- flatStop?: FlatStop;
410
387
  /** Set once a plan has been retired, so nothing re-arms mid-turn. */
411
388
  retired: boolean;
412
389
  /** What armed it: the prompt, or a ReAct iteration's intent (fallbk.md). */
413
390
  armedBy: "prompt" | "intent";
414
- /**
415
- * The user's request this plan serves, in their own words: the prompt for a
416
- * plan the prompt armed (set in `arm`), the turn's prompt for one an intent
417
- * match armed (set by the control server). Read only for the note of a plan
418
- * stopped at its decision, which quotes the request's condition sentences
419
- * (the service's segmentsbreakdown.md SB-18). Never sent anywhere.
420
- */
421
- request?: string;
422
391
  /**
423
392
  * The Claude Code session this plan serves, set by the control server. Its
424
393
  * steps run on that session's own proxies (executor.ts). Absent for `bir
@@ -443,25 +412,6 @@ export interface ReplayState {
443
412
  * paths, which resolve against the project directory as the host's do.
444
413
  */
445
414
  bashCwd?: string;
446
- /**
447
- * Which kind of row was handed out (segmented.md R-OUT-7). A `segment` is a
448
- * named sub-task of a recording rather than a whole task, and it is judged
449
- * against its own similarity gate. Absent from an older server, and then read
450
- * as `scenario` (R-COMPAT-2).
451
- */
452
- kind: "scenario" | "segment";
453
- /** Where a handed-out segment sits in its recording (R-OUT-8). */
454
- segment?: MatchSegment;
455
- /** Which of the segment's two keys scored (R-OUT-3). For logs. */
456
- key?: MatchKey;
457
- /** The cheap model's answer, when the score sat in the not-clear band. */
458
- verified?: MatchVerdict;
459
- /**
460
- * Segments of this plan's own recording that armed later in the same turn
461
- * (R-MONEY-4). Their share comes off this plan's baseline, so one recording's
462
- * steps are never counted in two baselines of one turn.
463
- */
464
- sharedWith: string[];
465
415
  /** Set when the plan handed the task to the model part-way (fallbk.md). */
466
416
  handover?: Handover;
467
417
  /**
@@ -483,11 +433,9 @@ export interface ReplayState {
483
433
  */
484
434
  diverging?: boolean;
485
435
  /**
486
- * Which gate declined, as a fixed code (segmented.md R-HIT-14). The prose
487
- * `why` that `decline()` logs stays free text; this is what code reads — the
488
- * position rule (R-OUT-6) reports a position only for `known_bad_first_step`,
489
- * and reading prose for that would break the first time a sentence was
490
- * reworded.
436
+ * Which gate declined, as a fixed code. The prose `why` that `decline()`
437
+ * logs stays free text; this is what code and the report read, and reading
438
+ * prose would break the first time a sentence was reworded.
491
439
  */
492
440
  declined?: DeclineCode;
493
441
  /**
@@ -507,10 +455,7 @@ export interface ReplayState {
507
455
  * A plan that finished its work stops costing at that moment: the agent's
508
456
  * later work in the same turn is the agent's, not this plan's. A plan that
509
457
  * handed over or diverged takes no mark, because the follow-on work is the
510
- * direct consequence of its stopping (R-MONEY-3, R-FALL-5) — except a plan
511
- * stopped at its decision after a step ran: it did all it was for, and the
512
- * agent's decision and the half it chose are the agent's own (the service's
513
- * segmentsbreakdown.md SB-26).
458
+ * direct consequence of its stopping (R-MONEY-3, R-FALL-5).
514
459
  */
515
460
  retiredMark?: unknown;
516
461
  retiredAt?: number;
@@ -578,10 +523,7 @@ export interface ReplayState {
578
523
  * copies are cut to 3,800 bytes, and the agent's work is built on them.
579
524
  */
580
525
  keepCalls?: boolean;
581
- /**
582
- * Those calls, in the order the plan made them, keyed by frame and step —
583
- * a sub-task called twice keeps both calls of each step.
584
- */
526
+ /** Those calls, in the order the plan made them, keyed by step. */
585
527
  turnCalls?: Map<string, TurnCall>;
586
528
  /** What they hold, in characters: bounded by {@link TURN_CALLS_MAX_CHARS}. */
587
529
  turnCallChars?: number;
@@ -624,7 +566,7 @@ export interface TurnCall {
624
566
  * Why a match did not arm. One code per gate of the ladder, so the caller can
625
567
  * act on a decline without parsing the sentence that explains it.
626
568
  */
627
- export type DeclineCode = "replay_disabled" | "not_ready" | "flatten_failed" | "known_bad_first_step" | "nondeterministic_first_step" | "unusable_first_step" | "coverage" | "missing_target" | "no_derive_key"
569
+ export type DeclineCode = "replay_disabled" | "not_ready" | "known_bad_first_step" | "nondeterministic_first_step" | "coverage" | "missing_target" | "no_derive_key"
628
570
  /** The service handed over no plan: this runner is too old for it. */
629
571
  | "runner_update_required"
630
572
  /**
@@ -711,16 +653,6 @@ export declare class ReplayController {
711
653
  */
712
654
  private hostSignals;
713
655
  constructor(opts: ReplayOptions);
714
- /**
715
- * Whether a handed-out segment may actually arm (segmented.md R-OUT-10).
716
- *
717
- * Only when the option says so. The recorder passes it on unless
718
- * `BIR_SEGMENT_ARM=0` (from 0.3.19; the service's segmentsbreakdown.md
719
- * SB-21); a controller built without it stays observe-only, asks for no
720
- * segment and arms none. The server enforces the same thing from its side
721
- * (R-OUT-9).
722
- */
723
- get segmentArm(): boolean;
724
656
  /** The plan's own delivery vehicle is never a scenario step. */
725
657
  isDirectTool(toolName: string): boolean;
726
658
  /**
@@ -758,16 +690,9 @@ export declare class ReplayController {
758
690
  * stops when that is before its end. For a host that steps through the plan
759
691
  * itself and must not have to pick the tool names out of a directive
760
692
  * written for a model — a reworded sentence would break every adapter in
761
- * the field. Built from the same entries the directive lists.
693
+ * the field. Built from the same steps the directive lists.
762
694
  */
763
695
  planData(state: ReplayState): PlanData | undefined;
764
- /**
765
- * Whether the plan's steps end in front of a decision (the service's
766
- * segmentsbreakdown.md SB-6): it runs the steps before it, then hands the
767
- * task back there. The control server gives such a plan a usage mark, so
768
- * that it is billed only up to the stop (SB-26).
769
- */
770
- stopsAtDecision(state: ReplayState): boolean;
771
696
  /**
772
697
  * Take back a plan that armed and has run nothing, as a decline.
773
698
  *
@@ -914,9 +839,9 @@ export declare class ReplayController {
914
839
  */
915
840
  postTool(state: ReplayState, toolUseId: string, output: string, failed?: string, how?: PostToolOptions): boolean;
916
841
  /**
917
- * A steer plan whose cursor reached its end: in front of a parked step (or a
918
- * call the service could not answer), which hands over; otherwise it ran to
919
- * its end — and from here every call is the model's own.
842
+ * A steer plan whose cursor reached its end: in front of a parked step,
843
+ * which hands over; otherwise it ran to its end — and from here every call
844
+ * is the model's own.
920
845
  */
921
846
  private finishSteer;
922
847
  /**
@@ -1057,10 +982,6 @@ export declare class ReplayController {
1057
982
  * there is nothing to be similar *to* and nothing to decline. It books no
1058
983
  * execution either — there is no ticket, and inventing a saving for a manual
1059
984
  * invocation is exactly the kind of number a ledger must never contain.
1060
- *
1061
- * One served stop is kept: a plan's decision (the service's
1062
- * segmentsbreakdown.md SB-6). The run stops in front of it, and `stopped`
1063
- * says so with the reason `decision`.
1064
985
  */
1065
986
  runAdHoc(scenario: SerializedScenario, prompt: string, wrapped: ReadonlySet<string>): Promise<{
1066
987
  ok: boolean;
@@ -1130,23 +1051,10 @@ export declare class ReplayController {
1130
1051
  */
1131
1052
  private handOver;
1132
1053
  /**
1133
- * Which kind of stop a plan's end is (plan-services.md D8). The stopping
1134
- * step's own served reason wins — the calculation's verdict is more exact
1135
- * than a counter — then a call the service could not answer, then a parked
1136
- * step.
1137
- */
1138
- private stopKindOf;
1139
- /**
1140
- * A divergence's bundle that ended at the plan's decision (SB-17): logged
1141
- * as `handOver` logs every other hand-over, and its usage mark taken there
1142
- * when a step of the plan ran (SB-26).
1143
- */
1144
- private decidedInDivergence;
1145
- /**
1146
- * The steps before flat position `bound` that ran, 1-based, and the ones
1147
- * their tests left out (AC5) — the plan cursor's own, and a divergence
1148
- * bundle's (`extra`). `left` is empty when no step was left out; `ran` is
1149
- * then not filled, since every step before `bound` ran.
1054
+ * The steps before position `bound` that ran, 1-based, and the ones their
1055
+ * tests left out (AC5) — the plan cursor's own, and a divergence bundle's
1056
+ * (`extra`). `left` is empty when no step was left out; `ran` is then not
1057
+ * filled, since every step before `bound` ran.
1150
1058
  */
1151
1059
  private ranBefore;
1152
1060
  private noteFor;
@@ -1255,12 +1163,6 @@ export declare class ReplayController {
1255
1163
  /** Outcomes only move forward; `not_steered` is the floor (§11.1). */
1256
1164
  private upgrade;
1257
1165
  private retire;
1258
- /**
1259
- * Where the plan's work ended, for its bill: now, and the transcript's
1260
- * watermark now. Taken at a completing retire, and at a decision hand-over
1261
- * after a step ran (the service's segmentsbreakdown.md SB-26).
1262
- */
1263
- private markRetired;
1264
1166
  }
1265
1167
  /** The subset of `RunMatch` replay consumes. Structural, so tests need no recorder. */
1266
1168
  export interface RunMatchLike {
@@ -1272,11 +1174,6 @@ export interface RunMatchLike {
1272
1174
  fallback?: {
1273
1175
  maxStepFailures: number;
1274
1176
  };
1275
- /** All absent from an older server (segmented.md R-COMPAT-2). */
1276
- kind?: "scenario" | "segment";
1277
- segment?: MatchSegment;
1278
- key?: MatchKey;
1279
- verified?: MatchVerdict;
1280
1177
  /** The frozen name, beside the runtime intent the plan runs on (R-INTENT-12). */
1281
1178
  intentName?: string;
1282
1179
  /** Why the service handed over no plan, when it says. Read for `runner_update_required`. */
@@ -1295,8 +1192,7 @@ export declare function knownBadStepIndex(steps: readonly SerializedScenarioStep
1295
1192
  *
1296
1193
  * A step that carries `stop` was decided by the service — `null` means run it,
1297
1194
  * even when its count is past the limit: its retry is due. A step without the
1298
- * field came from an older service, and the old counter rule decides it. Both
1299
- * can sit in one chain, since a called segment is served on its own terms.
1195
+ * field came from an older service, and the old counter rule decides it.
1300
1196
  */
1301
1197
  export declare function stopIndex(steps: readonly SerializedScenarioStep[], maxStepFailures: number | undefined): number | undefined;
1302
1198
  export {};