run method
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;
}