run method

Future<WorldDifferentialResult> run(
  1. WorldManifest manifest,
  2. String featureDir
)

Run the gate for manifest; featureDir receives the report (tdd/world-differential-report.json).

Implementation

Future<WorldDifferentialResult> run(
  WorldManifest manifest,
  String featureDir,
) async {
  // World binding: full semantics, seeded from the manifest.
  final worldRuntime = WorldRuntime(manifest, binding: WorldBinding.world);
  final worldResults = await worldRuntime.executeScenario();

  // Real binding: the direct real-adapter harness (no world
  // semantics).
  final realRuntime = WorldRuntime(manifest, binding: WorldBinding.real);
  final realResults = await realRuntime.executeScenario();

  final byBehavior = {for (final r in realResults) r.behavior: r};

  final rows = <WorldDiffRow>[];
  for (final world in worldResults) {
    final real = byBehavior[world.behavior];
    if (real == null) {
      rows.add(
        WorldDiffRow(
          behavior: world.behavior,
          clazz: DiffClass.drift,
          worldPassed: world.passed,
          realPassed: false,
          payloadsEqual: false,
          detail: 'behavior missing from the real-lane program',
        ),
      );
      continue;
    }
    final payloadsEqual =
        world.succeeded &&
        real.succeeded &&
        _payloadEquals(world.result, real.result);

    final row = _classify(world, real, payloadsEqual);
    rows.add(row);
  }

  // Every declared storm must have fired at least once in the world
  // run — scan the play ledger for each storm's fingerprint (failed
  // and partial plays both name their storm).
  final unrehearsed = <String>[];
  for (final storm in manifest.storms) {
    final fired = worldRuntime.plays.any(
      (play) =>
          play.outcome != 'ok' && play.detail.contains('storm ${storm.name}'),
    );
    if (!fired) {
      unrehearsed.add(storm.name);
    }
  }

  final verdict = rows.any((r) => r.clazz == DiffClass.drift)
      ? WorldDiffVerdict.drift
      : WorldDiffVerdict.pass;
  final result = WorldDifferentialResult(
    verdict: verdict,
    rows: rows,
    unrehearsedStorms: unrehearsed,
    worldHash: manifest.worldHash,
  );

  // The committed report artifact.
  final reportPath = p.join(
    featureDir,
    'tdd',
    'world-differential-report.json',
  );
  final reportFile = File(reportPath);
  await reportFile.parent.create(recursive: true);
  await reportFile.writeAsString(
    '${const JsonEncoder.withIndent('  ').convert(result.toDocument())}\n',
  );
  return result;
}