buildCommitteeShadowReceipt function

CommitteeShadowReceipt buildCommitteeShadowReceipt({
  1. required CommitteeSelectionRun run,
  2. required CommitteeRouteObservation route,
  3. required List<CommitteeLaneReceipt> lanes,
  4. Iterable<String> missingFields = const [],
  5. bool truncated = false,
})

Assembles ONE receipt from already-observed facts — PURE: no filesystem, no inference, no tree.

lanes arrive derived (CommitteeLaneReceipt.derive); every identity, omission set and accounting block below is computed here, so a replay over the recorded columns reproduces the receipt byte for byte.

Implementation

CommitteeShadowReceipt buildCommitteeShadowReceipt({
  required CommitteeSelectionRun run,
  required CommitteeRouteObservation route,
  required List<CommitteeLaneReceipt> lanes,
  Iterable<String> missingFields = const [],
  bool truncated = false,
}) {
  final selected = run.selection.selectedRubricIds;
  final omitted = [
    for (final id in run.fullRubricIds)
      if (!selected.contains(id)) id,
  ];
  final actionLaneIds = [
    for (final lane in lanes)
      if (kCommitteeActionGrades.contains(lane.grade ?? '')) lane.rubricId,
  ];
  final selectedLanes = [
    for (final lane in lanes)
      if (selected.contains(lane.rubricId)) lane,
  ];
  return CommitteeShadowReceipt(
    sampleId: committeeSampleId(
      policyVersion: run.policyVersion,
      stage: run.stage,
      workBeadId: run.workBeadId,
      round: run.round,
      evidenceDigest: run.selection.evidenceDigest,
    ),
    joinId: committeeJoinId(
      stage: run.stage,
      workBeadId: run.workBeadId,
      round: run.round,
      routeParentPath: route.parentPath,
    ),
    run: run,
    route: route,
    selectedRubricIds: selected,
    omittedRubricIds: omitted,
    lanes: lanes,
    actionLaneIds: actionLaneIds,
    gateDisposition: committeeGateDispositionFor(
      adverse: lanes.any(
        (lane) => kCommitteeAdverseGrades.contains(lane.grade ?? ''),
      ),
      routeType: route.type,
    ),
    downstreamJoinKeys: {
      'workBeadId': run.workBeadId,
      'round': '${run.round}',
      'stage': run.stage.wire,
      'routeNodePath': route.nodePath,
      'siblingScope': '${route.parentPath}/',
    },
    actual: committeeUsageAccounting(lanes: lanes),
    classifier: committeeUsageAccounting(
      lanes: const [],
      attempts: run.attempts,
    ),
    counterfactual: committeeUsageAccounting(
      lanes: selectedLanes,
      attempts: run.attempts,
    ),
    truncated: truncated || run.evidence.truncated,
    missingFields: missingFields,
  );
}