Add higher-layer rehost trace probes
This commit is contained in:
parent
dc7215f720
commit
6bfe4d043f
7 changed files with 741 additions and 22 deletions
|
|
@ -167,6 +167,12 @@ guessing one more derived leaf field from nearby offsets, and the checked-in
|
||||||
[`docs/rehost-queue.md`](docs/rehost-queue.md) file is now the control surface for that loop:
|
[`docs/rehost-queue.md`](docs/rehost-queue.md) file is now the control surface for that loop:
|
||||||
after each commit, check the queue and continue unless the queue is empty, a real blocker remains,
|
after each commit, check the queue and continue unless the queue is empty, a real blocker remains,
|
||||||
or approval is needed. A checked-in
|
or approval is needed. A checked-in
|
||||||
|
The same runtime surface now also exposes higher-layer blocker probes:
|
||||||
|
`runtime inspect-periodic-company-service-trace <save.gms>`,
|
||||||
|
`runtime inspect-region-service-trace <save.gms>`, and
|
||||||
|
`runtime inspect-infrastructure-asset-trace <save.gms>`, so the next city-connection /
|
||||||
|
linked-transit slices can start from explicit owner-seam blockers instead of another generic save
|
||||||
|
scan. A checked-in
|
||||||
`EventEffects` export now exists too in
|
`EventEffects` export now exists too in
|
||||||
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now
|
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now
|
||||||
exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered
|
exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,11 @@ use rrt_runtime::{
|
||||||
SmpRt3105PackedProfileBlock, SmpSaveLoadSummary, WinInspectionReport, execute_step_command,
|
SmpRt3105PackedProfileBlock, SmpSaveLoadSummary, WinInspectionReport, execute_step_command,
|
||||||
extract_pk4_entry_file, inspect_campaign_exe_file, inspect_cargo_economy_sources_with_bindings,
|
extract_pk4_entry_file, inspect_campaign_exe_file, inspect_cargo_economy_sources_with_bindings,
|
||||||
inspect_cargo_skin_pk4, inspect_cargo_types_dir, inspect_pk4_file,
|
inspect_cargo_skin_pk4, inspect_cargo_types_dir, inspect_pk4_file,
|
||||||
inspect_save_company_and_chairman_analysis_file,
|
inspect_save_company_and_chairman_analysis_file, inspect_save_infrastructure_asset_trace_file,
|
||||||
|
inspect_save_periodic_company_service_trace_file,
|
||||||
inspect_save_placed_structure_dynamic_side_buffer_file,
|
inspect_save_placed_structure_dynamic_side_buffer_file,
|
||||||
inspect_save_region_queued_notice_records_file, inspect_smp_file,
|
inspect_save_region_queued_notice_records_file, inspect_save_region_service_trace_file,
|
||||||
inspect_unclassified_save_collection_headers_file, inspect_win_file,
|
inspect_smp_file, inspect_unclassified_save_collection_headers_file, inspect_win_file,
|
||||||
load_runtime_snapshot_document, load_runtime_state_import, load_save_slice_file,
|
load_runtime_snapshot_document, load_runtime_state_import, load_save_slice_file,
|
||||||
project_save_slice_to_runtime_state_import, save_runtime_overlay_import_document,
|
project_save_slice_to_runtime_state_import, save_runtime_overlay_import_document,
|
||||||
save_runtime_save_slice_document, save_runtime_snapshot_document,
|
save_runtime_save_slice_document, save_runtime_snapshot_document,
|
||||||
|
|
@ -133,6 +134,15 @@ enum Command {
|
||||||
RuntimeInspectSaveCompanyChairman {
|
RuntimeInspectSaveCompanyChairman {
|
||||||
smp_path: PathBuf,
|
smp_path: PathBuf,
|
||||||
},
|
},
|
||||||
|
RuntimeInspectPeriodicCompanyServiceTrace {
|
||||||
|
smp_path: PathBuf,
|
||||||
|
},
|
||||||
|
RuntimeInspectRegionServiceTrace {
|
||||||
|
smp_path: PathBuf,
|
||||||
|
},
|
||||||
|
RuntimeInspectInfrastructureAssetTrace {
|
||||||
|
smp_path: PathBuf,
|
||||||
|
},
|
||||||
RuntimeInspectSaveRegionQueuedNoticeRecords {
|
RuntimeInspectSaveRegionQueuedNoticeRecords {
|
||||||
smp_path: PathBuf,
|
smp_path: PathBuf,
|
||||||
},
|
},
|
||||||
|
|
@ -294,6 +304,24 @@ struct RuntimeSaveCompanyChairmanAnalysisOutput {
|
||||||
analysis: rrt_runtime::SmpSaveCompanyChairmanAnalysisReport,
|
analysis: rrt_runtime::SmpSaveCompanyChairmanAnalysisReport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct RuntimePeriodicCompanyServiceTraceOutput {
|
||||||
|
path: String,
|
||||||
|
trace: rrt_runtime::SmpPeriodicCompanyServiceTraceReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct RuntimeRegionServiceTraceOutput {
|
||||||
|
path: String,
|
||||||
|
trace: rrt_runtime::SmpRegionServiceTraceReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct RuntimeInfrastructureAssetTraceOutput {
|
||||||
|
path: String,
|
||||||
|
trace: rrt_runtime::SmpInfrastructureAssetTraceReport,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct RuntimeSaveSliceExportOutput {
|
struct RuntimeSaveSliceExportOutput {
|
||||||
path: String,
|
path: String,
|
||||||
|
|
@ -865,6 +893,15 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
Command::RuntimeInspectSaveCompanyChairman { smp_path } => {
|
Command::RuntimeInspectSaveCompanyChairman { smp_path } => {
|
||||||
run_runtime_inspect_save_company_chairman(&smp_path)?;
|
run_runtime_inspect_save_company_chairman(&smp_path)?;
|
||||||
}
|
}
|
||||||
|
Command::RuntimeInspectPeriodicCompanyServiceTrace { smp_path } => {
|
||||||
|
run_runtime_inspect_periodic_company_service_trace(&smp_path)?;
|
||||||
|
}
|
||||||
|
Command::RuntimeInspectRegionServiceTrace { smp_path } => {
|
||||||
|
run_runtime_inspect_region_service_trace(&smp_path)?;
|
||||||
|
}
|
||||||
|
Command::RuntimeInspectInfrastructureAssetTrace { smp_path } => {
|
||||||
|
run_runtime_inspect_infrastructure_asset_trace(&smp_path)?;
|
||||||
|
}
|
||||||
Command::RuntimeInspectSaveRegionQueuedNoticeRecords { smp_path } => {
|
Command::RuntimeInspectSaveRegionQueuedNoticeRecords { smp_path } => {
|
||||||
run_runtime_inspect_save_region_queued_notice_records(&smp_path)?;
|
run_runtime_inspect_save_region_queued_notice_records(&smp_path)?;
|
||||||
}
|
}
|
||||||
|
|
@ -1077,6 +1114,28 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
||||||
smp_path: PathBuf::from(path),
|
smp_path: PathBuf::from(path),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
[command, subcommand, path]
|
||||||
|
if command == "runtime"
|
||||||
|
&& subcommand == "inspect-periodic-company-service-trace" =>
|
||||||
|
{
|
||||||
|
Ok(Command::RuntimeInspectPeriodicCompanyServiceTrace {
|
||||||
|
smp_path: PathBuf::from(path),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
[command, subcommand, path]
|
||||||
|
if command == "runtime" && subcommand == "inspect-region-service-trace" =>
|
||||||
|
{
|
||||||
|
Ok(Command::RuntimeInspectRegionServiceTrace {
|
||||||
|
smp_path: PathBuf::from(path),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
[command, subcommand, path]
|
||||||
|
if command == "runtime" && subcommand == "inspect-infrastructure-asset-trace" =>
|
||||||
|
{
|
||||||
|
Ok(Command::RuntimeInspectInfrastructureAssetTrace {
|
||||||
|
smp_path: PathBuf::from(path),
|
||||||
|
})
|
||||||
|
}
|
||||||
[command, subcommand, path]
|
[command, subcommand, path]
|
||||||
if command == "runtime"
|
if command == "runtime"
|
||||||
&& subcommand == "inspect-save-region-queued-notice-records" =>
|
&& subcommand == "inspect-save-region-queued-notice-records" =>
|
||||||
|
|
@ -1303,7 +1362,7 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => Err(
|
_ => Err(
|
||||||
"usage: rrt-cli [validate [repo-root] | finance eval <snapshot.json> | finance diff <left.json> <right.json> | runtime validate-fixture <fixture.json> | runtime summarize-fixture <fixture.json> | runtime export-fixture-state <fixture.json> <snapshot.json> | runtime diff-state <left.json> <right.json> | runtime summarize-state <snapshot.json> | runtime import-state <input.json> <snapshot.json> | runtime inspect-smp <file.smp> | runtime summarize-save-load <file.smp> | runtime load-save-slice <file.smp> | runtime inspect-save-company-chairman <file.smp> | runtime inspect-save-region-queued-notice-records <file.smp> | runtime inspect-placed-structure-dynamic-side-buffer <file.smp> | runtime inspect-unclassified-save-collections <file.smp> | runtime import-save-state <file.smp> <snapshot.json> | runtime export-save-slice <file.smp> <save-slice.json> | runtime export-overlay-import <snapshot.json> <save-slice.json> <overlay-import.json> | runtime inspect-pk4 <file.pk4> | runtime inspect-cargo-types <CargoTypes-dir> | runtime inspect-cargo-skins <Cargo106.PK4> | runtime inspect-cargo-economy-sources <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-production-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-price-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-win <file.win> | runtime extract-pk4-entry <file.pk4> <entry-name> <output-path> | runtime inspect-campaign-exe <RT3.exe> | runtime compare-classic-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-105-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-candidate-table <file1> <file2> [fileN...] | runtime compare-recipe-book-lines <file1> <file2> [fileN...] | runtime compare-setup-payload-core <file1> <file2> [fileN...] | runtime compare-setup-launch-payload <file1> <file2> [fileN...] | runtime compare-post-special-conditions-scalars <file1> <file2> [fileN...] | runtime scan-candidate-table-headers <root-dir> | runtime scan-special-conditions <root-dir> | runtime scan-aligned-runtime-rule-band <root-dir> | runtime scan-post-special-conditions-scalars <root-dir> | runtime scan-post-special-conditions-tail <root-dir> | runtime scan-recipe-book-lines <root-dir> | runtime export-profile-block <save.gms> <profile.json>]"
|
"usage: rrt-cli [validate [repo-root] | finance eval <snapshot.json> | finance diff <left.json> <right.json> | runtime validate-fixture <fixture.json> | runtime summarize-fixture <fixture.json> | runtime export-fixture-state <fixture.json> <snapshot.json> | runtime diff-state <left.json> <right.json> | runtime summarize-state <snapshot.json> | runtime import-state <input.json> <snapshot.json> | runtime inspect-smp <file.smp> | runtime summarize-save-load <file.smp> | runtime load-save-slice <file.smp> | runtime inspect-save-company-chairman <file.smp> | runtime inspect-periodic-company-service-trace <file.smp> | runtime inspect-region-service-trace <file.smp> | runtime inspect-infrastructure-asset-trace <file.smp> | runtime inspect-save-region-queued-notice-records <file.smp> | runtime inspect-placed-structure-dynamic-side-buffer <file.smp> | runtime inspect-unclassified-save-collections <file.smp> | runtime import-save-state <file.smp> <snapshot.json> | runtime export-save-slice <file.smp> <save-slice.json> | runtime export-overlay-import <snapshot.json> <save-slice.json> <overlay-import.json> | runtime inspect-pk4 <file.pk4> | runtime inspect-cargo-types <CargoTypes-dir> | runtime inspect-cargo-skins <Cargo106.PK4> | runtime inspect-cargo-economy-sources <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-production-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-price-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-win <file.win> | runtime extract-pk4-entry <file.pk4> <entry-name> <output-path> | runtime inspect-campaign-exe <RT3.exe> | runtime compare-classic-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-105-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-candidate-table <file1> <file2> [fileN...] | runtime compare-recipe-book-lines <file1> <file2> [fileN...] | runtime compare-setup-payload-core <file1> <file2> [fileN...] | runtime compare-setup-launch-payload <file1> <file2> [fileN...] | runtime compare-post-special-conditions-scalars <file1> <file2> [fileN...] | runtime scan-candidate-table-headers <root-dir> | runtime scan-special-conditions <root-dir> | runtime scan-aligned-runtime-rule-band <root-dir> | runtime scan-post-special-conditions-scalars <root-dir> | runtime scan-post-special-conditions-tail <root-dir> | runtime scan-recipe-book-lines <root-dir> | runtime export-profile-block <save.gms> <profile.json>]"
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
@ -1544,6 +1603,39 @@ fn run_runtime_inspect_save_company_chairman(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_runtime_inspect_periodic_company_service_trace(
|
||||||
|
smp_path: &Path,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let report = RuntimePeriodicCompanyServiceTraceOutput {
|
||||||
|
path: smp_path.display().to_string(),
|
||||||
|
trace: inspect_save_periodic_company_service_trace_file(smp_path)?,
|
||||||
|
};
|
||||||
|
println!("{}", serde_json::to_string_pretty(&report)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_runtime_inspect_region_service_trace(
|
||||||
|
smp_path: &Path,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let report = RuntimeRegionServiceTraceOutput {
|
||||||
|
path: smp_path.display().to_string(),
|
||||||
|
trace: inspect_save_region_service_trace_file(smp_path)?,
|
||||||
|
};
|
||||||
|
println!("{}", serde_json::to_string_pretty(&report)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_runtime_inspect_infrastructure_asset_trace(
|
||||||
|
smp_path: &Path,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let report = RuntimeInfrastructureAssetTraceOutput {
|
||||||
|
path: smp_path.display().to_string(),
|
||||||
|
trace: inspect_save_infrastructure_asset_trace_file(smp_path)?,
|
||||||
|
};
|
||||||
|
println!("{}", serde_json::to_string_pretty(&report)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn run_runtime_inspect_save_region_queued_notice_records(
|
fn run_runtime_inspect_save_region_queued_notice_records(
|
||||||
smp_path: &Path,
|
smp_path: &Path,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ pub use smp::{
|
||||||
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
||||||
SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock,
|
SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock,
|
||||||
SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe,
|
SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe,
|
||||||
SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit,
|
SmpHeaderVariantProbe, SmpInfrastructureAssetTraceReport, SmpInspectionReport, SmpKnownTagHit,
|
||||||
SmpLoadedCandidateAvailabilityTable, SmpLoadedCargoCatalog, SmpLoadedCargoCatalogEntry,
|
SmpLoadedCandidateAvailabilityTable, SmpLoadedCargoCatalog, SmpLoadedCargoCatalogEntry,
|
||||||
SmpLoadedChairmanProfileEntry, SmpLoadedChairmanProfileTable, SmpLoadedCompanyRoster,
|
SmpLoadedChairmanProfileEntry, SmpLoadedChairmanProfileTable, SmpLoadedCompanyRoster,
|
||||||
SmpLoadedCompanyRosterEntry, SmpLoadedEventRuntimeCollectionSummary,
|
SmpLoadedCompanyRosterEntry, SmpLoadedEventRuntimeCollectionSummary,
|
||||||
|
|
@ -108,31 +108,33 @@ pub use smp::{
|
||||||
SmpLoadedWorldFinanceNeighborhoodState, SmpLoadedWorldIssue37State,
|
SmpLoadedWorldFinanceNeighborhoodState, SmpLoadedWorldIssue37State,
|
||||||
SmpLocomotivePolicyFieldObservation, SmpLocomotivePolicyFloatAlignmentCandidate,
|
SmpLocomotivePolicyFieldObservation, SmpLocomotivePolicyFloatAlignmentCandidate,
|
||||||
SmpLocomotivePolicyNeighborhoodProbe, SmpPackedProfileWordLane,
|
SmpLocomotivePolicyNeighborhoodProbe, SmpPackedProfileWordLane,
|
||||||
SmpPostSpecialConditionsScalarLane, SmpPostSpecialConditionsScalarProbe,
|
SmpPeriodicCompanyServiceTraceReport, SmpPostSpecialConditionsScalarLane,
|
||||||
SmpPostTextFieldNeighborhoodProbe, SmpPostTextFloatAlignmentCandidate,
|
SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe,
|
||||||
SmpPostTextGroundedFieldObservation, SmpPreRecipeScalarPlateauLane,
|
SmpPostTextFloatAlignmentCandidate, SmpPostTextGroundedFieldObservation,
|
||||||
SmpPreRecipeScalarPlateauProbe, SmpPreamble, SmpPreambleWord, SmpRecipeBookLineSummary,
|
SmpPreRecipeScalarPlateauLane, SmpPreRecipeScalarPlateauProbe, SmpPreamble, SmpPreambleWord,
|
||||||
SmpRecipeBookSummaryBook, SmpRecipeBookSummaryProbe, SmpRt3105PackedProfileBlock,
|
SmpRecipeBookLineSummary, SmpRecipeBookSummaryBook, SmpRecipeBookSummaryProbe,
|
||||||
SmpRt3105PackedProfileProbe, SmpRt3105PostSpanBridgeProbe, SmpRt3105SaveBridgePayloadProbe,
|
SmpRegionServiceTraceReport, SmpRt3105PackedProfileBlock, SmpRt3105PackedProfileProbe,
|
||||||
SmpRt3105SaveNameTableEntry, SmpRt3105SaveNameTableProbe, SmpRuntimeAnchorCycleBlock,
|
SmpRt3105PostSpanBridgeProbe, SmpRt3105SaveBridgePayloadProbe, SmpRt3105SaveNameTableEntry,
|
||||||
SmpRuntimePostSpanHeaderCandidate, SmpRuntimePostSpanProbe, SmpRuntimeTrailerBlock,
|
SmpRt3105SaveNameTableProbe, SmpRuntimeAnchorCycleBlock, SmpRuntimePostSpanHeaderCandidate,
|
||||||
SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock, SmpSaveChairmanRecordAnalysisEntry,
|
SmpRuntimePostSpanProbe, SmpRuntimeTrailerBlock, SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock,
|
||||||
SmpSaveCompanyChairmanAnalysisReport, SmpSaveCompanyRecordAnalysisEntry, SmpSaveDwordCandidate,
|
SmpSaveChairmanRecordAnalysisEntry, SmpSaveCompanyChairmanAnalysisReport,
|
||||||
SmpSaveLoadCandidateTableSummary, SmpSaveLoadSummary,
|
SmpSaveCompanyRecordAnalysisEntry, SmpSaveDwordCandidate, SmpSaveLoadCandidateTableSummary,
|
||||||
SmpSavePlacedStructureDynamicSideBufferAlignmentProbe,
|
SmpSaveLoadSummary, SmpSavePlacedStructureDynamicSideBufferAlignmentProbe,
|
||||||
SmpSavePlacedStructureDynamicSideBufferNamePairSummary,
|
SmpSavePlacedStructureDynamicSideBufferNamePairSummary,
|
||||||
SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary,
|
SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary,
|
||||||
SmpSavePlacedStructureDynamicSideBufferProbe, SmpSaveRegionQueuedNoticeRecordProbe,
|
SmpSavePlacedStructureDynamicSideBufferProbe, SmpSaveRegionQueuedNoticeRecordProbe,
|
||||||
SmpSaveScalarCandidate, SmpSaveTaggedCollectionHeaderProbe, SmpSaveWorldEconomicTuningProbe,
|
SmpSaveScalarCandidate, SmpSaveTaggedCollectionHeaderProbe, SmpSaveWorldEconomicTuningProbe,
|
||||||
SmpSaveWorldFinanceNeighborhoodProbe, SmpSaveWorldIssue37Probe,
|
SmpSaveWorldFinanceNeighborhoodProbe, SmpSaveWorldIssue37Probe,
|
||||||
SmpSaveWorldSelectionRoleAnalysis, SmpSaveWorldSelectionRoleAnalysisEntry,
|
SmpSaveWorldSelectionRoleAnalysis, SmpSaveWorldSelectionRoleAnalysisEntry,
|
||||||
SmpSecondaryVariantProbe, SmpSharedHeader, SmpSpecialConditionEntry, SmpSpecialConditionsProbe,
|
SmpSecondaryVariantProbe, SmpServiceTraceBranchStatus, SmpSharedHeader,
|
||||||
|
SmpSpecialConditionEntry, SmpSpecialConditionsProbe,
|
||||||
inspect_save_company_and_chairman_analysis_bytes,
|
inspect_save_company_and_chairman_analysis_bytes,
|
||||||
inspect_save_company_and_chairman_analysis_file,
|
inspect_save_company_and_chairman_analysis_file, inspect_save_infrastructure_asset_trace_file,
|
||||||
|
inspect_save_periodic_company_service_trace_file,
|
||||||
inspect_save_placed_structure_dynamic_side_buffer_file,
|
inspect_save_placed_structure_dynamic_side_buffer_file,
|
||||||
inspect_save_region_queued_notice_records_file, inspect_smp_bytes, inspect_smp_file,
|
inspect_save_region_queued_notice_records_file, inspect_save_region_service_trace_file,
|
||||||
inspect_unclassified_save_collection_headers_file, load_save_slice_file,
|
inspect_smp_bytes, inspect_smp_file, inspect_unclassified_save_collection_headers_file,
|
||||||
load_save_slice_from_report,
|
load_save_slice_file, load_save_slice_from_report,
|
||||||
};
|
};
|
||||||
pub use step::{BoundaryEvent, ServiceEvent, StepCommand, StepResult, execute_step_command};
|
pub use step::{BoundaryEvent, ServiceEvent, StepCommand, StepResult, execute_step_command};
|
||||||
pub use summary::RuntimeSummary;
|
pub use summary::RuntimeSummary;
|
||||||
|
|
|
||||||
|
|
@ -2882,6 +2882,101 @@ pub struct SmpSaveCompanyChairmanAnalysisReport {
|
||||||
pub notes: Vec<String>,
|
pub notes: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpServiceTraceBranchStatus {
|
||||||
|
pub branch_name: String,
|
||||||
|
pub status: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub grounded_inputs: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub blocking_inputs: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub notes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpPeriodicCompanyServiceTraceEntry {
|
||||||
|
pub company_id: u32,
|
||||||
|
pub name: String,
|
||||||
|
pub active: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub linked_chairman_profile_id: Option<u32>,
|
||||||
|
pub preferred_locomotive_engine_type_raw_u8: u8,
|
||||||
|
pub city_connection_latch: bool,
|
||||||
|
pub linked_transit_latch: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub branches: Vec<SmpServiceTraceBranchStatus>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpPeriodicCompanyServiceTraceReport {
|
||||||
|
pub profile_family: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub selected_company_id: Option<u32>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub world_issue_37_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub world_finance_neighborhood_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub region_record_body_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub placed_structure_record_body_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub infrastructure_asset_side_buffer_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub companies: Vec<SmpPeriodicCompanyServiceTraceEntry>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub notes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpRegionServiceTraceEntry {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub profile_collection_count: Option<u32>,
|
||||||
|
pub policy_leading_f32_0_text: String,
|
||||||
|
pub policy_leading_f32_1_text: String,
|
||||||
|
pub policy_leading_f32_2_text: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub branches: Vec<SmpServiceTraceBranchStatus>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpRegionServiceTraceReport {
|
||||||
|
pub profile_family: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub region_collection_header_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub region_record_triplet_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub queued_notice_record_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub entries: Vec<SmpRegionServiceTraceEntry>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub notes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpInfrastructureAssetTraceReport {
|
||||||
|
pub profile_family: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub placed_structure_collection_header_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub placed_structure_record_triplet_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub side_buffer_present: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub side_buffer_decoded_embedded_name_row_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub side_buffer_unique_name_pair_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub triplet_alignment_overlap_count: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub branches: Vec<SmpServiceTraceBranchStatus>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub notes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct SmpLoadedSpecialConditionsTable {
|
pub struct SmpLoadedSpecialConditionsTable {
|
||||||
pub source_kind: String,
|
pub source_kind: String,
|
||||||
|
|
@ -3315,6 +3410,356 @@ pub fn inspect_save_region_queued_notice_records_file(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_service_trace_branch_status(
|
||||||
|
branch_name: &str,
|
||||||
|
status: &str,
|
||||||
|
grounded_inputs: &[&str],
|
||||||
|
blocking_inputs: &[&str],
|
||||||
|
notes: &[&str],
|
||||||
|
) -> SmpServiceTraceBranchStatus {
|
||||||
|
SmpServiceTraceBranchStatus {
|
||||||
|
branch_name: branch_name.to_string(),
|
||||||
|
status: status.to_string(),
|
||||||
|
grounded_inputs: grounded_inputs
|
||||||
|
.iter()
|
||||||
|
.map(|value| value.to_string())
|
||||||
|
.collect(),
|
||||||
|
blocking_inputs: blocking_inputs
|
||||||
|
.iter()
|
||||||
|
.map(|value| value.to_string())
|
||||||
|
.collect(),
|
||||||
|
notes: notes.iter().map(|value| value.to_string()).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inspect_save_periodic_company_service_trace_file(
|
||||||
|
path: &Path,
|
||||||
|
) -> Result<SmpPeriodicCompanyServiceTraceReport, Box<dyn std::error::Error>> {
|
||||||
|
let inspection = inspect_smp_file(path)?;
|
||||||
|
let analysis = inspect_save_company_and_chairman_analysis_file(path)?;
|
||||||
|
let profile_family = analysis.profile_family.clone();
|
||||||
|
let selected_company_id = analysis.selected_company_id;
|
||||||
|
let region_record_body_present = analysis.region_record_triplets.is_some();
|
||||||
|
let placed_structure_record_body_present = analysis.placed_structure_record_triplets.is_some();
|
||||||
|
let infrastructure_asset_side_buffer_present =
|
||||||
|
analysis.placed_structure_dynamic_side_buffer.is_some();
|
||||||
|
let world_issue_37_present = analysis.world_issue_37.is_some();
|
||||||
|
let world_finance_neighborhood_present = analysis.world_finance_neighborhood.is_some();
|
||||||
|
|
||||||
|
let companies = analysis
|
||||||
|
.company_entries
|
||||||
|
.iter()
|
||||||
|
.map(|entry| {
|
||||||
|
let mut branches = Vec::new();
|
||||||
|
branches.push(build_service_trace_branch_status(
|
||||||
|
"route_preference_override",
|
||||||
|
if entry.preferred_locomotive_engine_type_raw_u8 == 2 {
|
||||||
|
"grounded_electric_override_candidate"
|
||||||
|
} else {
|
||||||
|
"grounded_non_electric_or_inactive_override_candidate"
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
"company periodic side-latch trio",
|
||||||
|
"world route-preference byte",
|
||||||
|
"preferred locomotive engine-type lane",
|
||||||
|
],
|
||||||
|
&[],
|
||||||
|
&[
|
||||||
|
"This probe keeps the outer owner at the save-owned input level; the concrete runtime reader/apply/restore seam is already grounded separately.",
|
||||||
|
],
|
||||||
|
));
|
||||||
|
branches.push(build_service_trace_branch_status(
|
||||||
|
"annual_finance_policy",
|
||||||
|
"runnable_from_grounded_owner_state",
|
||||||
|
&[
|
||||||
|
"company market/cache owner state",
|
||||||
|
"periodic side-latches",
|
||||||
|
"world issue/timing owner state",
|
||||||
|
"derived annual-finance readers",
|
||||||
|
],
|
||||||
|
&[],
|
||||||
|
&[
|
||||||
|
"The shellless annual-finance helper is already rehosted on top of runtime-owned state.",
|
||||||
|
],
|
||||||
|
));
|
||||||
|
branches.push(build_service_trace_branch_status(
|
||||||
|
"city_connection_announcement",
|
||||||
|
"blocked_missing_region_and_infrastructure_asset_owner_seams",
|
||||||
|
&[
|
||||||
|
"company periodic side-latches",
|
||||||
|
"route-preference override seam",
|
||||||
|
"annual-finance sequencing owner",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"region pending/completion/one-shot/severity lanes",
|
||||||
|
"stable region id or class discriminator",
|
||||||
|
"placed-structure or infrastructure-asset consumer mapping",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"Current atlas evidence places this branch above both the region pending-bonus lane and infrastructure/placed-structure consumers.",
|
||||||
|
],
|
||||||
|
));
|
||||||
|
branches.push(build_service_trace_branch_status(
|
||||||
|
"linked_transit_roster_maintenance",
|
||||||
|
"blocked_missing_infrastructure_asset_consumer_mapping",
|
||||||
|
&[
|
||||||
|
"company linked-transit latch",
|
||||||
|
"route-preference override seam",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"placed-structure record-body semantics",
|
||||||
|
"0x38a5 infrastructure-asset consumer mapping",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"The save side now grounds the owner seams, but not yet the higher-layer consumer that turns them into roster or route actions.",
|
||||||
|
],
|
||||||
|
));
|
||||||
|
branches.push(build_service_trace_branch_status(
|
||||||
|
"industry_acquisition_side_branch",
|
||||||
|
"blocked_missing_near-city_owner_mapping",
|
||||||
|
&[
|
||||||
|
"periodic service outer owner",
|
||||||
|
"annual-finance ordering",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"near-city industry candidate owner seam",
|
||||||
|
"city or region peer linkage",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"The outer owner is bounded, but the concrete candidate/peer scan is not yet rehosted.",
|
||||||
|
],
|
||||||
|
));
|
||||||
|
SmpPeriodicCompanyServiceTraceEntry {
|
||||||
|
company_id: entry.company_id,
|
||||||
|
name: entry.name.clone(),
|
||||||
|
active: entry.active,
|
||||||
|
linked_chairman_profile_id: entry.linked_chairman_profile_id,
|
||||||
|
preferred_locomotive_engine_type_raw_u8: entry
|
||||||
|
.preferred_locomotive_engine_type_raw_u8,
|
||||||
|
city_connection_latch: entry.city_connection_latch,
|
||||||
|
linked_transit_latch: entry.linked_transit_latch,
|
||||||
|
branches,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut notes = Vec::new();
|
||||||
|
let _ = inspection;
|
||||||
|
notes.push(
|
||||||
|
"Periodic company service trace is intentionally an outer-owner probe: it reports save-owned branch inputs and blocker seams without serializing the full projected runtime reader state.".to_string(),
|
||||||
|
);
|
||||||
|
if region_record_body_present || placed_structure_record_body_present {
|
||||||
|
notes.push(
|
||||||
|
"The current blockers are no longer collection identity; they are missing higher-layer consumer semantics for the region and infrastructure/placed-structure owner seams.".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(SmpPeriodicCompanyServiceTraceReport {
|
||||||
|
profile_family,
|
||||||
|
selected_company_id,
|
||||||
|
world_issue_37_present,
|
||||||
|
world_finance_neighborhood_present,
|
||||||
|
region_record_body_present,
|
||||||
|
placed_structure_record_body_present,
|
||||||
|
infrastructure_asset_side_buffer_present,
|
||||||
|
companies,
|
||||||
|
notes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inspect_save_region_service_trace_file(
|
||||||
|
path: &Path,
|
||||||
|
) -> Result<SmpRegionServiceTraceReport, Box<dyn std::error::Error>> {
|
||||||
|
let analysis = inspect_save_company_and_chairman_analysis_file(path)?;
|
||||||
|
Ok(build_region_service_trace_report(&analysis))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inspect_save_infrastructure_asset_trace_file(
|
||||||
|
path: &Path,
|
||||||
|
) -> Result<SmpInfrastructureAssetTraceReport, Box<dyn std::error::Error>> {
|
||||||
|
let analysis = inspect_save_company_and_chairman_analysis_file(path)?;
|
||||||
|
Ok(build_infrastructure_asset_trace_report(&analysis))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_region_service_trace_report(
|
||||||
|
analysis: &SmpSaveCompanyChairmanAnalysisReport,
|
||||||
|
) -> SmpRegionServiceTraceReport {
|
||||||
|
let entries = analysis
|
||||||
|
.region_record_triplets
|
||||||
|
.as_ref()
|
||||||
|
.map(|probe| {
|
||||||
|
probe.entries
|
||||||
|
.iter()
|
||||||
|
.map(|entry| SmpRegionServiceTraceEntry {
|
||||||
|
name: entry.name.clone(),
|
||||||
|
profile_collection_count: entry
|
||||||
|
.profile_collection
|
||||||
|
.as_ref()
|
||||||
|
.map(|collection| collection.live_record_count),
|
||||||
|
policy_leading_f32_0_text: format!("{:.6}", entry.policy_leading_f32_0),
|
||||||
|
policy_leading_f32_1_text: format!("{:.6}", entry.policy_leading_f32_1),
|
||||||
|
policy_leading_f32_2_text: format!("{:.6}", entry.policy_leading_f32_2),
|
||||||
|
branches: vec![
|
||||||
|
build_service_trace_branch_status(
|
||||||
|
"pending_bonus_queue_seed",
|
||||||
|
"blocked_missing_pending_bonus_owner_lane",
|
||||||
|
&[
|
||||||
|
"region triplet envelope",
|
||||||
|
"embedded profile subcollection",
|
||||||
|
"policy float lanes",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"[region+0x276] pending amount lane",
|
||||||
|
"[region+0x25e] severity/source lane",
|
||||||
|
],
|
||||||
|
&["The queued kind-7 notice family is not obviously persisted in ordinary saves, so the pending queue must be treated as transient until a direct owner seam is found."],
|
||||||
|
),
|
||||||
|
build_service_trace_branch_status(
|
||||||
|
"city_connection_completion",
|
||||||
|
"blocked_missing_completion_and_one_shot_latches",
|
||||||
|
&[
|
||||||
|
"region triplet envelope",
|
||||||
|
"region name stem",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"[region+0x302] completion latch",
|
||||||
|
"[region+0x316] one-shot notice latch",
|
||||||
|
"stable region id or class discriminator",
|
||||||
|
],
|
||||||
|
&["The remaining region blocker is a separate owner seam for the latches the city-connection branch reads and writes."],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let mut notes = Vec::new();
|
||||||
|
notes.push(
|
||||||
|
"Region service trace treats the queued kind-7 notice family as transient runtime state until a persisted owner seam is found.".to_string(),
|
||||||
|
);
|
||||||
|
notes.push(
|
||||||
|
"The current region seam is strong enough to prove record-envelope ownership, profile subcollection ownership, and the absence of hidden 0x55f3 tail padding on grounded saves.".to_string(),
|
||||||
|
);
|
||||||
|
SmpRegionServiceTraceReport {
|
||||||
|
profile_family: analysis.profile_family.clone(),
|
||||||
|
region_collection_header_present: analysis.region_collection_header.is_some(),
|
||||||
|
region_record_triplet_count: analysis
|
||||||
|
.region_record_triplets
|
||||||
|
.as_ref()
|
||||||
|
.map(|probe| probe.record_count)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
queued_notice_record_count: analysis
|
||||||
|
.region_queued_notice_records
|
||||||
|
.as_ref()
|
||||||
|
.map(|probe| probe.entries.len())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
entries,
|
||||||
|
notes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_infrastructure_asset_trace_report(
|
||||||
|
analysis: &SmpSaveCompanyChairmanAnalysisReport,
|
||||||
|
) -> SmpInfrastructureAssetTraceReport {
|
||||||
|
let side_buffer = analysis.placed_structure_dynamic_side_buffer.as_ref();
|
||||||
|
let alignment = analysis
|
||||||
|
.placed_structure_dynamic_side_buffer_alignment
|
||||||
|
.as_ref();
|
||||||
|
let branches = vec![
|
||||||
|
build_service_trace_branch_status(
|
||||||
|
"infrastructure_asset_owner_seam",
|
||||||
|
if side_buffer.is_some() {
|
||||||
|
"grounded_separate_owner_seam"
|
||||||
|
} else {
|
||||||
|
"blocked_missing_side_buffer_owner_seam"
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
"0x38a5/0x38a6/0x38a7 tagged family",
|
||||||
|
"embedded 0x55f1 dual-name rows",
|
||||||
|
"compact 6-byte prefix regimes",
|
||||||
|
],
|
||||||
|
if side_buffer.is_some() {
|
||||||
|
&[]
|
||||||
|
} else {
|
||||||
|
&["0x38a5 owner seam"]
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
"This seam should be treated as infrastructure-asset state rather than as a compact alias of placed-structure triplets.",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
build_service_trace_branch_status(
|
||||||
|
"placed_structure_triplet_alias",
|
||||||
|
if alignment.is_some_and(|probe| probe.overlapping_name_pair_count == 0) {
|
||||||
|
"disproved_by_grounded_probe"
|
||||||
|
} else {
|
||||||
|
"unresolved"
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
"0x36b1 placed-structure triplet corpus",
|
||||||
|
"0x38a5 side-buffer name-pair corpus",
|
||||||
|
],
|
||||||
|
&[],
|
||||||
|
&[
|
||||||
|
"Grounded q.gms evidence currently shows zero overlap between the side-buffer name-pair corpus and the placed-structure triplet name-pair corpus.",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
build_service_trace_branch_status(
|
||||||
|
"city_connection_consumer_mapping",
|
||||||
|
"blocked_missing_infrastructure_asset_consumer_mapping",
|
||||||
|
&[
|
||||||
|
"grounded 0x38a5 owner seam",
|
||||||
|
"placed-structure triplet seam",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"higher-layer consumer dispatch mapping",
|
||||||
|
"compact prefix regime semantics",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"The remaining problem is how higher-layer service code consumes this separate seam, not whether the seam exists.",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
build_service_trace_branch_status(
|
||||||
|
"linked_transit_consumer_mapping",
|
||||||
|
"blocked_missing_infrastructure_asset_consumer_mapping",
|
||||||
|
&["grounded 0x38a5 owner seam", "company linked-transit latch"],
|
||||||
|
&[
|
||||||
|
"side-buffer consumer mapping",
|
||||||
|
"route or roster rebuild owner path",
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
"The next slice should target the consumer path above the side-buffer seam rather than another raw save scan.",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
let notes = vec![
|
||||||
|
"Infrastructure asset trace now makes the side-buffer-versus-triplet split explicit: owner seam identity is grounded, consumer semantics are still blocked.".to_string(),
|
||||||
|
];
|
||||||
|
SmpInfrastructureAssetTraceReport {
|
||||||
|
profile_family: analysis.profile_family.clone(),
|
||||||
|
placed_structure_collection_header_present: analysis
|
||||||
|
.placed_structure_collection_header
|
||||||
|
.is_some(),
|
||||||
|
placed_structure_record_triplet_count: analysis
|
||||||
|
.placed_structure_record_triplets
|
||||||
|
.as_ref()
|
||||||
|
.map(|probe| probe.record_count)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
side_buffer_present: side_buffer.is_some(),
|
||||||
|
side_buffer_decoded_embedded_name_row_count: side_buffer
|
||||||
|
.map(|probe| probe.decoded_embedded_name_row_count)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
side_buffer_unique_name_pair_count: side_buffer
|
||||||
|
.map(|probe| probe.unique_embedded_name_pair_count)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
triplet_alignment_overlap_count: alignment
|
||||||
|
.map(|probe| probe.overlapping_name_pair_count)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
branches,
|
||||||
|
notes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn inspect_smp_bytes(bytes: &[u8]) -> SmpInspectionReport {
|
pub fn inspect_smp_bytes(bytes: &[u8]) -> SmpInspectionReport {
|
||||||
inspect_bundle_bytes(bytes, None)
|
inspect_bundle_bytes(bytes, None)
|
||||||
}
|
}
|
||||||
|
|
@ -21058,4 +21503,149 @@ mod tests {
|
||||||
assert_eq!(alt_profile.profile_family, "rt3-105-alt-map-container-v1");
|
assert_eq!(alt_profile.profile_family, "rt3-105-alt-map-container-v1");
|
||||||
assert!(alt_profile.is_known_profile);
|
assert!(alt_profile.is_known_profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn empty_analysis_report() -> SmpSaveCompanyChairmanAnalysisReport {
|
||||||
|
SmpSaveCompanyChairmanAnalysisReport {
|
||||||
|
profile_family: "rt3-105-scenario-save-container-v1".to_string(),
|
||||||
|
selected_company_id: None,
|
||||||
|
selected_chairman_profile_id: None,
|
||||||
|
world_selection_context: None,
|
||||||
|
world_issue_37: None,
|
||||||
|
world_economic_tuning: None,
|
||||||
|
world_finance_neighborhood: None,
|
||||||
|
train_collection_header: None,
|
||||||
|
train_collection_directory: None,
|
||||||
|
region_collection_header: None,
|
||||||
|
region_record_triplets: None,
|
||||||
|
region_queued_notice_records: None,
|
||||||
|
placed_structure_collection_header: None,
|
||||||
|
placed_structure_record_triplets: None,
|
||||||
|
placed_structure_dynamic_side_buffer: None,
|
||||||
|
placed_structure_dynamic_side_buffer_alignment: None,
|
||||||
|
unclassified_tagged_collection_headers: Vec::new(),
|
||||||
|
company_entries: Vec::new(),
|
||||||
|
chairman_entries: Vec::new(),
|
||||||
|
notes: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn builds_region_service_trace_report_with_explicit_latch_blockers() {
|
||||||
|
let mut analysis = empty_analysis_report();
|
||||||
|
analysis.region_record_triplets = Some(SmpSaveRegionRecordTripletProbe {
|
||||||
|
profile_family: analysis.profile_family.clone(),
|
||||||
|
source_kind: "save-region-record-triplets".to_string(),
|
||||||
|
semantic_family: "marker09".to_string(),
|
||||||
|
records_tag_offset: 0,
|
||||||
|
close_tag_offset: 0,
|
||||||
|
record_count: 1,
|
||||||
|
entries: vec![SmpSaveRegionRecordTripletEntryProbe {
|
||||||
|
record_index: 0,
|
||||||
|
name: "Marker09".to_string(),
|
||||||
|
name_tag_relative_offset: 0,
|
||||||
|
policy_tag_relative_offset: 0,
|
||||||
|
profile_tag_relative_offset: 0,
|
||||||
|
policy_chunk_len: 0,
|
||||||
|
profile_chunk_len: 0,
|
||||||
|
policy_leading_f32_0: 368.0,
|
||||||
|
policy_leading_f32_1: 0.0,
|
||||||
|
policy_leading_f32_2: 92.0,
|
||||||
|
policy_reserved_dwords: Vec::new(),
|
||||||
|
policy_trailing_word: 0,
|
||||||
|
policy_trailing_word_hex: "0x0000".to_string(),
|
||||||
|
profile_collection: Some(SmpSaveRegionProfileCollectionProbe {
|
||||||
|
direct_collection_flag: 1,
|
||||||
|
entry_stride: 0x22,
|
||||||
|
live_id_bound: 17,
|
||||||
|
live_record_count: 17,
|
||||||
|
entry_start_relative_offset: 0,
|
||||||
|
trailing_padding_len: 0,
|
||||||
|
entries: Vec::new(),
|
||||||
|
}),
|
||||||
|
}],
|
||||||
|
evidence: Vec::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let trace = build_region_service_trace_report(&analysis);
|
||||||
|
assert_eq!(trace.region_record_triplet_count, 1);
|
||||||
|
assert_eq!(trace.queued_notice_record_count, 0);
|
||||||
|
assert_eq!(trace.entries.len(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
trace.entries[0].branches[0].status,
|
||||||
|
"blocked_missing_pending_bonus_owner_lane"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
trace.entries[0].branches[1].status,
|
||||||
|
"blocked_missing_completion_and_one_shot_latches"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn builds_infrastructure_asset_trace_report_with_alias_disproved_status() {
|
||||||
|
let mut analysis = empty_analysis_report();
|
||||||
|
analysis.placed_structure_record_triplets =
|
||||||
|
Some(SmpSavePlacedStructureRecordTripletProbe {
|
||||||
|
profile_family: analysis.profile_family.clone(),
|
||||||
|
source_kind: "save-placed-structure-triplets".to_string(),
|
||||||
|
semantic_family: "placed-structure-triplets".to_string(),
|
||||||
|
records_tag_offset: 0,
|
||||||
|
close_tag_offset: 0,
|
||||||
|
record_count: 2057,
|
||||||
|
entries: Vec::new(),
|
||||||
|
evidence: Vec::new(),
|
||||||
|
});
|
||||||
|
analysis.placed_structure_dynamic_side_buffer =
|
||||||
|
Some(SmpSavePlacedStructureDynamicSideBufferProbe {
|
||||||
|
profile_family: analysis.profile_family.clone(),
|
||||||
|
source_kind: "save-side-buffer".to_string(),
|
||||||
|
semantic_family: "infrastructure-asset".to_string(),
|
||||||
|
metadata_tag_offset: 0,
|
||||||
|
records_tag_offset: 0,
|
||||||
|
close_tag_offset: 0,
|
||||||
|
records_span_len: 0,
|
||||||
|
direct_record_stride: 6,
|
||||||
|
direct_record_stride_hex: "0x00000006".to_string(),
|
||||||
|
live_id_bound: 3865,
|
||||||
|
live_id_bound_hex: "0x00000f19".to_string(),
|
||||||
|
live_record_count: 3865,
|
||||||
|
live_record_count_hex: "0x00000f19".to_string(),
|
||||||
|
prefix_leading_dword: 0xff000000,
|
||||||
|
prefix_leading_dword_hex: "0xff000000".to_string(),
|
||||||
|
prefix_trailing_word: 1,
|
||||||
|
prefix_trailing_word_hex: "0x0001".to_string(),
|
||||||
|
prefix_separator_byte: 0xff,
|
||||||
|
prefix_separator_byte_hex: "0xff".to_string(),
|
||||||
|
first_embedded_name_tag_relative_offset: 0x20,
|
||||||
|
embedded_name_tag_count: 138,
|
||||||
|
decoded_embedded_name_row_count: 138,
|
||||||
|
unique_compact_prefix_pattern_count: 7,
|
||||||
|
prefix_leading_dword_matching_embedded_profile_tag_count: 17,
|
||||||
|
unique_embedded_name_pair_count: 5,
|
||||||
|
first_embedded_primary_name: Some("TrackCapST_Cap.3dp".to_string()),
|
||||||
|
first_embedded_secondary_name: Some("Infrastructure".to_string()),
|
||||||
|
embedded_name_row_samples: Vec::new(),
|
||||||
|
compact_prefix_pattern_summaries: Vec::new(),
|
||||||
|
name_pair_summaries: Vec::new(),
|
||||||
|
evidence: Vec::new(),
|
||||||
|
});
|
||||||
|
analysis.placed_structure_dynamic_side_buffer_alignment =
|
||||||
|
Some(SmpSavePlacedStructureDynamicSideBufferAlignmentProbe {
|
||||||
|
unique_side_buffer_name_pair_count: 5,
|
||||||
|
unique_triplet_name_pair_count: 56,
|
||||||
|
overlapping_name_pair_count: 0,
|
||||||
|
side_buffer_row_count: 138,
|
||||||
|
side_buffer_rows_with_matching_triplet_name_pair_count: 0,
|
||||||
|
side_buffer_rows_without_matching_triplet_name_pair_count: 138,
|
||||||
|
triplet_name_pairs_without_side_buffer_match_count: 56,
|
||||||
|
matched_name_pair_samples: Vec::new(),
|
||||||
|
unmatched_side_buffer_name_pair_samples: Vec::new(),
|
||||||
|
evidence: Vec::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let trace = build_infrastructure_asset_trace_report(&analysis);
|
||||||
|
assert!(trace.side_buffer_present);
|
||||||
|
assert_eq!(trace.triplet_alignment_overlap_count, 0);
|
||||||
|
assert_eq!(trace.branches[0].status, "grounded_separate_owner_seam");
|
||||||
|
assert_eq!(trace.branches[1].status, "disproved_by_grounded_probe");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,12 @@ The highest-value next passes are now:
|
||||||
`docs/rehost-queue.md` file is the control surface for that work loop, and after each commit the
|
`docs/rehost-queue.md` file is the control surface for that work loop, and after each commit the
|
||||||
next queue item should run unless the queue is empty, a real blocker remains, or approval is
|
next queue item should run unless the queue is empty, a real blocker remains, or approval is
|
||||||
needed
|
needed
|
||||||
|
- `rrt-runtime` now also exposes higher-layer probe commands for the current blocked frontier:
|
||||||
|
`runtime inspect-periodic-company-service-trace <save.gms>`,
|
||||||
|
`runtime inspect-region-service-trace <save.gms>`, and
|
||||||
|
`runtime inspect-infrastructure-asset-trace <save.gms>`. These reports make the current
|
||||||
|
shellless city-connection / linked-transit blockers explicit as missing owner seams rather than
|
||||||
|
generic “still unresolved” residue.
|
||||||
- a checked-in `EventEffects` export now exists at
|
- a checked-in `EventEffects` export now exists at
|
||||||
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
|
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
|
||||||
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`
|
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@ Working rule:
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
|
- Follow the new higher-layer probe outputs instead of another blind save scan:
|
||||||
|
`runtime inspect-infrastructure-asset-trace <save.gms>` now shows that the `0x38a5`
|
||||||
|
infrastructure-asset seam is grounded and the old alias hypothesis is disproved on `q.gms`, so
|
||||||
|
the next placed-structure slice should target the consumer mapping above that seam rather than
|
||||||
|
more collection discovery.
|
||||||
- Reconstruct the save-side region record body on top of the newly corrected non-direct tagged
|
- Reconstruct the save-side region record body on top of the newly corrected non-direct tagged
|
||||||
region seam (`0x5209/0x520a/0x520b`, stride hint `0x06`, `Marker09` record stems) now that the
|
region seam (`0x5209/0x520a/0x520b`, stride hint `0x06`, `Marker09` record stems) now that the
|
||||||
`0x55f3` payload is known to be fully consumed by the embedded profile collection on grounded
|
`0x55f3` payload is known to be fully consumed by the embedded profile collection on grounded
|
||||||
|
|
@ -65,6 +70,18 @@ Working rule:
|
||||||
|
|
||||||
## Recently Done
|
## Recently Done
|
||||||
|
|
||||||
|
- `rrt-runtime` now exposes three higher-layer probe surfaces and matching CLI inspectors:
|
||||||
|
`runtime inspect-periodic-company-service-trace <save.gms>`,
|
||||||
|
`runtime inspect-region-service-trace <save.gms>`, and
|
||||||
|
`runtime inspect-infrastructure-asset-trace <save.gms>`. These reports separate grounded outer
|
||||||
|
owner inputs, runnable shellless branches, and explicit missing owner seams instead of leaving
|
||||||
|
the current city-connection / linked-transit frontier as an opaque blocker.
|
||||||
|
- Those same probes now also sharpen the next queue choice on grounded real saves: the periodic
|
||||||
|
company outer owner shows annual finance and route-preference override as grounded shellless
|
||||||
|
branches while city-connection and linked-transit stay blocked on region/infrastructure owner
|
||||||
|
seams; the region trace keeps the queued kind-`7` notice family on the transient side; and the
|
||||||
|
infrastructure trace now makes the `0x38a5` consumer-mapping blocker first-class after
|
||||||
|
disproving any alias to the `0x36b1` placed-structure triplet corpus.
|
||||||
- Save inspection now splits the shared `0x5209/0x520a/0x520b` family correctly: the smaller
|
- Save inspection now splits the shared `0x5209/0x520a/0x520b` family correctly: the smaller
|
||||||
direct `0x1d5` collection is the live train family and now exposes a live-entry directory rooted
|
direct `0x1d5` collection is the live train family and now exposes a live-entry directory rooted
|
||||||
at metadata dword `16`, while the actual region family is the larger non-direct `Marker09`
|
at metadata dword `16`, while the actual region family is the larger non-direct `Marker09`
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,12 @@ The process rule for the remaining runtime work is explicit too: prefer rehostin
|
||||||
real reader/setter families over guessing leaf fields, and use `docs/rehost-queue.md` as the
|
real reader/setter families over guessing leaf fields, and use `docs/rehost-queue.md` as the
|
||||||
checked-in control surface for the work loop. After each commit, check that queue and continue
|
checked-in control surface for the work loop. After each commit, check that queue and continue
|
||||||
unless the queue is empty, a real blocker remains, or approval is needed.
|
unless the queue is empty, a real blocker remains, or approval is needed.
|
||||||
|
The same control surface now also has matching runtime probes:
|
||||||
|
`runtime inspect-periodic-company-service-trace <save.gms>`,
|
||||||
|
`runtime inspect-region-service-trace <save.gms>`, and
|
||||||
|
`runtime inspect-infrastructure-asset-trace <save.gms>`. Use those first when the next blocked
|
||||||
|
frontier is “which higher-layer owner seam is still missing?” rather than “which raw save
|
||||||
|
collection exists?”.
|
||||||
That same owner seam now also derives live coupon burden totals directly from saved bond slots,
|
That same owner seam now also derives live coupon burden totals directly from saved bond slots,
|
||||||
which gives later finance service work a bounded runtime reader instead of another synthetic
|
which gives later finance service work a bounded runtime reader instead of another synthetic
|
||||||
finance leaf.
|
finance leaf.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue