diff --git a/README.md b/README.md index 62b32e3..f0e8685 100644 --- a/README.md +++ b/README.md @@ -108,8 +108,8 @@ dialog notes. The same periodic service now also carries the annual bond lane's issued principal totals as first-class runtime summary state, which is the owner seam behind the later debt-news family, and it now carries the paired issued-share and repurchased-share counts behind the equity-offering and `2887` buyback news tails too. Runtime summaries now also expose the -grounded retired-versus-issued relation directly, without guessing the exact `2882..2886` -headline selector. `simulation_service_periodic_boundary_work` is now beginning to use that same owner +grounded retired-versus-issued relation directly, and annual finance service now maps that same +comparison onto the exact debt headline selectors `2882..2886`. `simulation_service_periodic_boundary_work` is now beginning to use that same owner surface too: the runtime chooses one annual-finance action per active company and already commits the shellless creditor-pressure-bankruptcy, deep-distress-bankruptcy, dividend-adjustment, stock-repurchase, stock-issue, and bond-issue branches by mutating owned company activity, diff --git a/crates/rrt-runtime/src/runtime.rs b/crates/rrt-runtime/src/runtime.rs index 61e3571..dcc3cf6 100644 --- a/crates/rrt-runtime/src/runtime.rs +++ b/crates/rrt-runtime/src/runtime.rs @@ -3674,11 +3674,17 @@ pub fn runtime_annual_finance_news_family_candidate_label( RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy | RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback => Some("2881"), RuntimeCompanyAnnualFinancePolicyAction::BondIssue => { - runtime_annual_bond_principal_flow_relation_label( + match runtime_annual_bond_principal_flow_relation_label( retired_principal_total, issued_principal_total, - ) - .map(|_| "2882_2886") + ) { + Some("retired_equals_issued") => Some("2882"), + Some("issued_exceeds_retired") => Some("2883"), + Some("retired_exceeds_issued") => Some("2884"), + Some("retired_only") => Some("2885"), + Some("issued_only") => Some("2886"), + _ => None, + } } RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase => { (repurchased_share_count > 0).then_some("2887") @@ -8453,6 +8459,60 @@ mod tests { ); } + #[test] + fn maps_annual_bond_news_selector_from_principal_flow_relation() { + assert_eq!( + runtime_annual_finance_news_family_candidate_label( + RuntimeCompanyAnnualFinancePolicyAction::BondIssue, + 500_000, + 500_000, + 0, + 0, + ), + Some("2882") + ); + assert_eq!( + runtime_annual_finance_news_family_candidate_label( + RuntimeCompanyAnnualFinancePolicyAction::BondIssue, + 350_000, + 1_000_000, + 0, + 0, + ), + Some("2883") + ); + assert_eq!( + runtime_annual_finance_news_family_candidate_label( + RuntimeCompanyAnnualFinancePolicyAction::BondIssue, + 900_000, + 500_000, + 0, + 0, + ), + Some("2884") + ); + assert_eq!( + runtime_annual_finance_news_family_candidate_label( + RuntimeCompanyAnnualFinancePolicyAction::BondIssue, + 350_000, + 0, + 0, + 0, + ), + Some("2885") + ); + assert_eq!( + runtime_annual_finance_news_family_candidate_label( + RuntimeCompanyAnnualFinancePolicyAction::BondIssue, + 0, + 500_000, + 0, + 0, + ), + Some("2886") + ); + } + #[test] fn annual_bond_policy_stays_eligible_for_repayment_without_new_issue() { let mut year_stat_family_qword_bits = vec![ diff --git a/crates/rrt-runtime/src/step.rs b/crates/rrt-runtime/src/step.rs index 35bc282..e633af9 100644 --- a/crates/rrt-runtime/src/step.rs +++ b/crates/rrt-runtime/src/step.rs @@ -3288,7 +3288,7 @@ mod tests { .service_state .annual_finance_last_news_family_candidates .get(&24), - Some(&"2882_2886".to_string()) + Some(&"2886".to_string()) ); assert_eq!(state.companies[0].current_cash, 100_000); assert_eq!(state.service_state.company_market_state[&24].bond_count, 1); @@ -3324,8 +3324,7 @@ mod tests { .any(|event| event.kind == "annual_finance_policy" && event.applied_effect_count == 1 && event.mutated_company_ids == vec![24] - && event.finance_news_family_candidates.get(&24) - == Some(&"2882_2886".to_string())) + && event.finance_news_family_candidates.get(&24) == Some(&"2886".to_string())) ); } @@ -3454,7 +3453,7 @@ mod tests { .service_state .annual_finance_last_news_family_candidates .get(&25), - Some(&"2882_2886".to_string()) + Some(&"2885".to_string()) ); assert_eq!(state.companies[0].current_cash, 550_000); assert_eq!(state.companies[0].debt, 0); @@ -3487,8 +3486,7 @@ mod tests { .any(|event| event.kind == "annual_finance_policy" && event.applied_effect_count == 1 && event.mutated_company_ids == vec![25] - && event.finance_news_family_candidates.get(&25) - == Some(&"2882_2886".to_string())) + && event.finance_news_family_candidates.get(&25) == Some(&"2885".to_string())) ); } @@ -3618,7 +3616,7 @@ mod tests { .service_state .annual_finance_last_news_family_candidates .get(&26), - Some(&"2882_2886".to_string()) + Some(&"2883".to_string()) ); assert_eq!(state.companies[0].current_cash, 250_000); assert_eq!(state.companies[0].debt, 1_000_000); @@ -3663,8 +3661,7 @@ mod tests { .any(|event| event.kind == "annual_finance_policy" && event.applied_effect_count == 1 && event.mutated_company_ids == vec![26] - && event.finance_news_family_candidates.get(&26) - == Some(&"2882_2886".to_string())) + && event.finance_news_family_candidates.get(&26) == Some(&"2883".to_string())) ); } diff --git a/docs/README.md b/docs/README.md index 89d0106..f5fbd15 100644 --- a/docs/README.md +++ b/docs/README.md @@ -159,8 +159,8 @@ The highest-value next passes are now: service surface now also carries the per-cycle retired-versus-issued principal totals that feed the later debt-news family plus the issued-share and repurchased-share counts behind the later equity-offering and buyback news tails; runtime summaries now also expose the grounded - retired-versus-issued relation directly while still leaving the exact `2882..2886` selector on - the shell-owned side + retired-versus-issued relation directly, and annual finance service now maps that same relation + onto the exact debt headline selectors `2882..2886` - the project rule on the remaining closure work is now explicit too: when one runtime-facing field is still ambiguous, prefer rehosting the owning source state or real reader/setter family first instead of guessing another derived leaf field from neighboring raw offsets diff --git a/docs/runtime-rehost-plan.md b/docs/runtime-rehost-plan.md index 85ef6ad..c8ebe75 100644 --- a/docs/runtime-rehost-plan.md +++ b/docs/runtime-rehost-plan.md @@ -238,8 +238,8 @@ and periodic boundary service now commits the same shellless matured-bond repay/ stopping at the staging reader. That same service seam now also carries the retired-versus-issued principal totals needed by the later debt-news tail, plus the issued-share and repurchased-share counts needed by the later equity-offering and buyback news tails. Runtime summaries also expose -the grounded retired-versus-issued relation directly while the exact `2882..2886` selector remains -shell-owned. +the grounded retired-versus-issued relation directly, and annual finance service now maps that +relation onto the exact debt headline selectors `2882..2886`. The annual dividend-adjustment lane now rides that same seam too: the runtime now rehosts the shared year-or-control-transfer metric reader, the board-approved dividend ceiling helper, and the full annual dividend branch over owned cash, public float, current dividend, and building-growth