@renzrollon/interlock 1.2.1 → 1.3.1

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.
package/lib/run.mjs CHANGED
@@ -64,6 +64,7 @@ import { classifySurface } from './surface.mjs'
64
64
  import { buildChecklist } from './conformance.mjs'
65
65
  import { record as recordAutonomy } from './autonomy.mjs'
66
66
  import { writeResumeCard } from './resume-card.mjs'
67
+ import { summarizePlan } from './plan-summary.mjs'
67
68
  import {
68
69
  applyReplan,
69
70
  batchOutcomes,
@@ -439,7 +440,17 @@ export const RELAY_STEP_FIELDS = Object.freeze([
439
440
  'reason',
440
441
  // The control-plane ping model `run start` decided (design D3). The driver
441
442
  // sets its relay pings' model from this field and from nothing else.
442
- 'pingModel'
443
+ 'pingModel',
444
+ // For a second reader, the ship meter's wave board, and read by neither
445
+ // driver (draw-the-wave-board-in-the-meter-pane design D1): the step's wave
446
+ // and batch positions, a verify step's skip flag, the ids a recorded batch
447
+ // names, and the plan summary the adoption and replan steps carry.
448
+ 'waveIndex',
449
+ 'batchIndex',
450
+ 'batchCount',
451
+ 'skipped',
452
+ 'recorded',
453
+ 'plan'
443
454
  ])
444
455
 
445
456
  /**
@@ -2582,6 +2593,12 @@ function adoptPlan(ctx, manifest, plan) {
2582
2593
  if (slotsBanner && first && typeof first === 'object') {
2583
2594
  first.banners = [...(Array.isArray(first.banners) ? first.banners : []), slotsBanner]
2584
2595
  }
2596
+ // The waves that will run, once, for the meter's board (design D3): the
2597
+ // state's batches, which a `maxParallel` override re-chunked, with the
2598
+ // planner's own deferral records.
2599
+ if (first && typeof first === 'object' && first.action !== 'halt') {
2600
+ first.plan = summarizePlan(state, { deferred: plan.deferred })
2601
+ }
2585
2602
  return first
2586
2603
  }
2587
2604
 
@@ -3033,6 +3050,13 @@ export function runRecordBatch(ctx, { results, hostRecords }) {
3033
3050
  if (verdict.claimDerived) banners.push(claimDerivedBanner())
3034
3051
  if (verdict.overrides.length) banners.push(overrideBanner(verdict.overrides))
3035
3052
 
3053
+ // The lane that stopped early, plus anything the recorder found no result for
3054
+ // at all. Neither is ticked and neither is a failure. One expression for the
3055
+ // tally and for the step's `recorded`, so the two cannot disagree (design D2).
3056
+ const notAttemptedOf = counts => [
3057
+ ...unattempted,
3058
+ ...counts.recordedNotAttempted.filter(id => !unattempted.includes(id))
3059
+ ]
3036
3060
  verdict.waves.forEach(counts => {
3037
3061
  manifest.waves.push({
3038
3062
  wave: pending.wave,
@@ -3041,12 +3065,7 @@ export function runRecordBatch(ctx, { results, hostRecords }) {
3041
3065
  ok: counts.ok,
3042
3066
  failed: counts.failed,
3043
3067
  failedIds: counts.failedIds,
3044
- // The lane that stopped early, plus anything the recorder found no result
3045
- // for at all. Neither is ticked and neither is a failure.
3046
- notAttempted: [
3047
- ...unattempted,
3048
- ...counts.recordedNotAttempted.filter(id => !unattempted.includes(id))
3049
- ]
3068
+ notAttempted: notAttemptedOf(counts)
3050
3069
  })
3051
3070
  })
3052
3071
 
@@ -3068,7 +3087,17 @@ export function runRecordBatch(ctx, { results, hostRecords }) {
3068
3087
  }
3069
3088
 
3070
3089
  manifest.banners.push(...banners)
3071
- return finishStep(ctx, manifest, decorate(ctx, nextRaw, manifest, { banners }))
3090
+ const recordedStep = decorate(ctx, nextRaw, manifest, { banners })
3091
+ // What this batch recorded, for the meter's board (design D2): set here, on
3092
+ // the step record-batch returns, so no other subcommand can emit it.
3093
+ if (recordedStep && typeof recordedStep === 'object') {
3094
+ recordedStep.recorded = {
3095
+ ok: verdict.tickIds,
3096
+ failed: verdict.waves.flatMap(counts => counts.failedIds),
3097
+ notAttempted: [...new Set(verdict.waves.flatMap(notAttemptedOf))]
3098
+ }
3099
+ }
3100
+ return finishStep(ctx, manifest, recordedStep)
3072
3101
  }
3073
3102
 
3074
3103
  // --- run judge --------------------------------------------------------------
@@ -3479,7 +3508,12 @@ export function runReplan(ctx, { results, hostRecords }) {
3479
3508
  ctx.warn('an implementer agent-spawn was not recorded on replan')
3480
3509
  return finishStep(ctx, manifest, trajectoryHaltStep('agent-spawn', LANE_SPAWN_APPEND_FAILED))
3481
3510
  }
3482
- return finishStep(ctx, manifest, decorate(ctx, nextRaw, manifest))
3511
+ const revisedStep = decorate(ctx, nextRaw, manifest)
3512
+ // The revised waves replace the adopted ones on the meter's board (design D3).
3513
+ if (revisedStep && typeof revisedStep === 'object' && revisedStep.action !== 'halt') {
3514
+ revisedStep.plan = summarizePlan(after)
3515
+ }
3516
+ return finishStep(ctx, manifest, revisedStep)
3483
3517
  }
3484
3518
 
3485
3519
  // --- run next ---------------------------------------------------------------