From a9906f8bad55dcb7da64ba986147d1c74931ff51 Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Sun, 19 Apr 2026 02:36:41 -0700 Subject: [PATCH] Add compact dispatch count summary command --- crates/rrt-cli/src/main.rs | 111 ++++++++++++++++++++++++++++++------- docs/rehost-queue.md | 17 ++++-- 2 files changed, 102 insertions(+), 26 deletions(-) diff --git a/crates/rrt-cli/src/main.rs b/crates/rrt-cli/src/main.rs index ddd967f..4b32124 100644 --- a/crates/rrt-cli/src/main.rs +++ b/crates/rrt-cli/src/main.rs @@ -131,6 +131,9 @@ enum Command { RuntimeInspectCompactEventDispatchCluster { root_path: PathBuf, }, + RuntimeInspectCompactEventDispatchClusterCounts { + root_path: PathBuf, + }, RuntimeSummarizeSaveLoad { smp_path: PathBuf, }, @@ -305,6 +308,12 @@ struct RuntimeCompactEventDispatchClusterOutput { report: RuntimeCompactEventDispatchClusterReport, } +#[derive(Debug, Serialize)] +struct RuntimeCompactEventDispatchClusterCountsOutput { + root_path: String, + report: RuntimeCompactEventDispatchClusterCountsReport, +} + #[derive(Debug, Serialize)] struct RuntimeCompactEventDispatchClusterReport { maps_scanned: usize, @@ -324,6 +333,21 @@ struct RuntimeCompactEventDispatchClusterReport { BTreeMap>, } +#[derive(Debug, Serialize)] +struct RuntimeCompactEventDispatchClusterCountsReport { + maps_scanned: usize, + maps_with_event_runtime_collection: usize, + maps_with_dispatch_strip_records: usize, + dispatch_strip_record_count: usize, + dispatch_strip_records_with_trigger_kind: usize, + dispatch_strip_records_missing_trigger_kind: usize, + dispatch_strip_payload_families: BTreeMap, + dispatch_descriptor_occurrence_counts: BTreeMap, + dispatch_descriptor_map_counts: BTreeMap, + unknown_descriptor_ids: Vec, + unknown_descriptor_special_condition_label_matches: Vec, +} + #[derive(Debug, Clone, Serialize)] struct RuntimeCompactEventDispatchClusterOccurrence { path: String, @@ -991,6 +1015,9 @@ fn real_main() -> Result<(), Box> { Command::RuntimeInspectCompactEventDispatchCluster { root_path } => { run_runtime_inspect_compact_event_dispatch_cluster(&root_path)?; } + Command::RuntimeInspectCompactEventDispatchClusterCounts { root_path } => { + run_runtime_inspect_compact_event_dispatch_cluster_counts(&root_path)?; + } Command::RuntimeSummarizeSaveLoad { smp_path } => { run_runtime_summarize_save_load(&smp_path)?; } @@ -1224,6 +1251,14 @@ fn parse_command() -> Result> { root_path: PathBuf::from(root_path), }) } + [command, subcommand, root_path] + if command == "runtime" + && subcommand == "inspect-compact-event-dispatch-cluster-counts" => + { + Ok(Command::RuntimeInspectCompactEventDispatchClusterCounts { + root_path: PathBuf::from(root_path), + }) + } [command, subcommand, path] if command == "runtime" && subcommand == "summarize-save-load" => { @@ -1508,7 +1543,7 @@ fn parse_command() -> Result> { }) } _ => Err( - "usage: rrt-cli [validate [repo-root] | finance eval | finance diff | runtime validate-fixture | runtime summarize-fixture | runtime export-fixture-state | runtime diff-state | runtime summarize-state | runtime import-state | runtime inspect-smp | runtime inspect-candidate-table | runtime inspect-compact-event-dispatch-cluster | runtime summarize-save-load | runtime load-save-slice | runtime inspect-save-company-chairman | runtime inspect-save-placed-structure-triplets | runtime compare-region-fixed-row-runs | runtime inspect-periodic-company-service-trace | runtime inspect-region-service-trace | runtime inspect-infrastructure-asset-trace | runtime inspect-save-region-queued-notice-records | runtime inspect-placed-structure-dynamic-side-buffer | runtime inspect-unclassified-save-collections | runtime import-save-state | runtime export-save-slice | runtime export-overlay-import | runtime inspect-pk4 | runtime inspect-cargo-types | runtime inspect-cargo-skins | runtime inspect-cargo-economy-sources | runtime inspect-cargo-production-selector | runtime inspect-cargo-price-selector | runtime inspect-win | runtime extract-pk4-entry | runtime inspect-campaign-exe | runtime compare-classic-profile [saveN.gms...] | runtime compare-105-profile [saveN.gms...] | runtime compare-candidate-table [fileN...] | runtime compare-recipe-book-lines [fileN...] | runtime compare-setup-payload-core [fileN...] | runtime compare-setup-launch-payload [fileN...] | runtime compare-post-special-conditions-scalars [fileN...] | runtime scan-candidate-table-headers | runtime scan-special-conditions | runtime scan-aligned-runtime-rule-band | runtime scan-post-special-conditions-scalars | runtime scan-post-special-conditions-tail | runtime scan-recipe-book-lines | runtime export-profile-block ]" + "usage: rrt-cli [validate [repo-root] | finance eval | finance diff | runtime validate-fixture | runtime summarize-fixture | runtime export-fixture-state | runtime diff-state | runtime summarize-state | runtime import-state | runtime inspect-smp | runtime inspect-candidate-table | runtime inspect-compact-event-dispatch-cluster | runtime inspect-compact-event-dispatch-cluster-counts | runtime summarize-save-load | runtime load-save-slice | runtime inspect-save-company-chairman | runtime inspect-save-placed-structure-triplets | runtime compare-region-fixed-row-runs | runtime inspect-periodic-company-service-trace | runtime inspect-region-service-trace | runtime inspect-infrastructure-asset-trace | runtime inspect-save-region-queued-notice-records | runtime inspect-placed-structure-dynamic-side-buffer | runtime inspect-unclassified-save-collections | runtime import-save-state | runtime export-save-slice | runtime export-overlay-import | runtime inspect-pk4 | runtime inspect-cargo-types | runtime inspect-cargo-skins | runtime inspect-cargo-economy-sources | runtime inspect-cargo-production-selector | runtime inspect-cargo-price-selector | runtime inspect-win | runtime extract-pk4-entry | runtime inspect-campaign-exe | runtime compare-classic-profile [saveN.gms...] | runtime compare-105-profile [saveN.gms...] | runtime compare-candidate-table [fileN...] | runtime compare-recipe-book-lines [fileN...] | runtime compare-setup-payload-core [fileN...] | runtime compare-setup-launch-payload [fileN...] | runtime compare-post-special-conditions-scalars [fileN...] | runtime scan-candidate-table-headers | runtime scan-special-conditions | runtime scan-aligned-runtime-rule-band | runtime scan-post-special-conditions-scalars | runtime scan-post-special-conditions-tail | runtime scan-recipe-book-lines | runtime export-profile-block ]" .into(), ), } @@ -1716,6 +1751,45 @@ fn run_runtime_inspect_smp(smp_path: &Path) -> Result<(), Box Result<(), Box> { + let report = build_runtime_compact_event_dispatch_cluster_report(root_path)?; + let output = RuntimeCompactEventDispatchClusterOutput { + root_path: root_path.display().to_string(), + report, + }; + println!("{}", serde_json::to_string_pretty(&output)?); + Ok(()) +} + +fn run_runtime_inspect_compact_event_dispatch_cluster_counts( + root_path: &Path, +) -> Result<(), Box> { + let report = build_runtime_compact_event_dispatch_cluster_report(root_path)?; + let output = RuntimeCompactEventDispatchClusterCountsOutput { + root_path: root_path.display().to_string(), + report: RuntimeCompactEventDispatchClusterCountsReport { + maps_scanned: report.maps_scanned, + maps_with_event_runtime_collection: report.maps_with_event_runtime_collection, + maps_with_dispatch_strip_records: report.maps_with_dispatch_strip_records, + dispatch_strip_record_count: report.dispatch_strip_record_count, + dispatch_strip_records_with_trigger_kind: report + .dispatch_strip_records_with_trigger_kind, + dispatch_strip_records_missing_trigger_kind: report + .dispatch_strip_records_missing_trigger_kind, + dispatch_strip_payload_families: report.dispatch_strip_payload_families, + dispatch_descriptor_occurrence_counts: report.dispatch_descriptor_occurrence_counts, + dispatch_descriptor_map_counts: report.dispatch_descriptor_map_counts, + unknown_descriptor_ids: report.unknown_descriptor_ids, + unknown_descriptor_special_condition_label_matches: report + .unknown_descriptor_special_condition_label_matches, + }, + }; + println!("{}", serde_json::to_string_pretty(&output)?); + Ok(()) +} + +fn build_runtime_compact_event_dispatch_cluster_report( + root_path: &Path, +) -> Result> { let mut input_paths = Vec::new(); collect_compact_event_dispatch_cluster_input_paths(root_path, &mut input_paths)?; input_paths.sort(); @@ -1838,26 +1912,21 @@ fn run_runtime_inspect_compact_event_dispatch_cluster( }) .collect::>(); - let report = RuntimeCompactEventDispatchClusterOutput { - root_path: root_path.display().to_string(), - report: RuntimeCompactEventDispatchClusterReport { - maps_scanned: input_paths.len(), - maps_with_event_runtime_collection, - maps_with_dispatch_strip_records, - dispatch_strip_record_count, - dispatch_strip_records_with_trigger_kind, - dispatch_strip_records_missing_trigger_kind, - dispatch_strip_payload_families, - dispatch_descriptor_occurrence_counts, - dispatch_descriptor_map_counts, - dispatch_descriptor_occurrences, - unknown_descriptor_ids, - unknown_descriptor_special_condition_label_matches, - unknown_descriptor_occurrences, - }, - }; - println!("{}", serde_json::to_string_pretty(&report)?); - Ok(()) + Ok(RuntimeCompactEventDispatchClusterReport { + maps_scanned: input_paths.len(), + maps_with_event_runtime_collection, + maps_with_dispatch_strip_records, + dispatch_strip_record_count, + dispatch_strip_records_with_trigger_kind, + dispatch_strip_records_missing_trigger_kind, + dispatch_strip_payload_families, + dispatch_descriptor_occurrence_counts, + dispatch_descriptor_map_counts, + dispatch_descriptor_occurrences, + unknown_descriptor_ids, + unknown_descriptor_special_condition_label_matches, + unknown_descriptor_occurrences, + }) } fn run_runtime_summarize_save_load(smp_path: &Path) -> Result<(), Box> { diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index 2ae7d38..29e98e5 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -268,11 +268,18 @@ Working rule: mutation-capable rows in those sampled maps. - the widened compact-cluster probe now makes that same gap first-class too: `runtime inspect-compact-event-dispatch-cluster ` now reports all dispatch-strip - descriptor occurrences, their `trigger_kind`, and payload family instead of only unknown - descriptor ids. On `Texas Tea.gmp`, the widened report now shows `548 Add Building Port01`, - `8 Economic Status`, and `43 Company Variable 1` all arriving on - `real_packed_nondirect_compact_v1` rows with `trigger_kind = null`, so the next pass can work - from a checked probe rather than ad hoc `inspect-smp` scrapes. + descriptor occurrences, their `trigger_kind`, payload family, and the aggregated + `dispatch_descriptor_occurrence_counts` / `dispatch_descriptor_map_counts` summaries instead of + only unknown descriptor ids. On `Texas Tea.gmp`, the widened report now shows + `548 Add Building Port01`, `8 Economic Status`, and `43 Company Variable 1` all arriving on + `real_packed_nondirect_compact_v1` rows with `trigger_kind = null`, while the count summary + reports `Company Variable 1 = 4` occurrences and the other two once each, so the next pass can + work from a checked scalable probe rather than ad hoc `inspect-smp` scrapes. + - the scalable summary sibling is grounded too: + `runtime inspect-compact-event-dispatch-cluster-counts ` reuses the same analysis + but emits only the corpus-level count fields, so the next broader map-install pass no longer + needs to wade through every occurrence payload just to compare descriptor or trigger-kind + coverage. - cross-map probing now gives a better static-analysis lead too: `British Isles.gmp` shows no current `0x00431b20` dispatch-strip rows, `Germany.gmp` stays on `Game Variable 1` plus `Company Variable 3..4`, while `Texas Tea.gmp` adds `Economic Status`