Carry bond count into annual finance state

This commit is contained in:
Jan Petykiewicz 2026-04-17 21:16:42 -07:00
commit 5bf903137f
8 changed files with 41 additions and 3 deletions

View file

@ -73,7 +73,9 @@ market reader now exposes outstanding shares, assigned shares, public float, rou
price, salary lanes, bonus amount, and issue-calendar words from the owned annual-finance state price, salary lanes, bonus amount, and issue-calendar words from the owned annual-finance state
instead of leaving that logic spread across summary helpers. The same annual-finance state now also instead of leaving that logic spread across summary helpers. The same annual-finance state now also
derives elapsed years since founding, last dividend, and last bankruptcy from the runtime calendar, derives elapsed years since founding, last dividend, and last bankruptcy from the runtime calendar,
which lines up directly with the grounded annual finance-policy gates in the atlas. A checked-in which lines up directly with the grounded annual finance-policy gates in the atlas. Live bond-slot
count is now carried through the same owned company market and annual-finance state too, which
matches the stock-capital branch gate that requires at least two live bonds. A checked-in
The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we
should prefer rehosting the owning source state or the real reader/setter family rather than should prefer rehosting the owning source state or the real reader/setter family rather than
guessing one more derived leaf field from nearby offsets. A checked-in guessing one more derived leaf field from nearby offsets. A checked-in

View file

@ -92,6 +92,8 @@ pub struct ExpectedRuntimeSummary {
#[serde(default)] #[serde(default)]
pub selected_company_outstanding_shares: Option<u32>, pub selected_company_outstanding_shares: Option<u32>,
#[serde(default)] #[serde(default)]
pub selected_company_bond_count: Option<u8>,
#[serde(default)]
pub selected_company_assigned_share_pool: Option<u32>, pub selected_company_assigned_share_pool: Option<u32>,
#[serde(default)] #[serde(default)]
pub selected_company_unassigned_share_pool: Option<u32>, pub selected_company_unassigned_share_pool: Option<u32>,
@ -609,6 +611,14 @@ impl ExpectedRuntimeSummary {
)); ));
} }
} }
if let Some(value) = self.selected_company_bond_count {
if actual.selected_company_bond_count != Some(value) {
mismatches.push(format!(
"selected_company_bond_count mismatch: expected {value}, got {:?}",
actual.selected_company_bond_count
));
}
}
if let Some(value) = self.selected_company_assigned_share_pool { if let Some(value) = self.selected_company_assigned_share_pool {
if actual.selected_company_assigned_share_pool != Some(value) { if actual.selected_company_assigned_share_pool != Some(value) {
mismatches.push(format!( mismatches.push(format!(

View file

@ -5041,6 +5041,7 @@ mod tests {
merger_cooldown_year: Some(1838), merger_cooldown_year: Some(1838),
market_state: Some(crate::RuntimeCompanyMarketState { market_state: Some(crate::RuntimeCompanyMarketState {
outstanding_shares: 20_000, outstanding_shares: 20_000,
bond_count: 2,
mutable_support_scalar_raw_u32: 0x3f99999a, mutable_support_scalar_raw_u32: 0x3f99999a,
young_company_support_scalar_raw_u32: 0x42700000, young_company_support_scalar_raw_u32: 0x42700000,
support_progress_word: 12, support_progress_word: 12,
@ -5087,6 +5088,7 @@ mod tests {
merger_cooldown_year: None, merger_cooldown_year: None,
market_state: Some(crate::RuntimeCompanyMarketState { market_state: Some(crate::RuntimeCompanyMarketState {
outstanding_shares: 18_000, outstanding_shares: 18_000,
bond_count: 1,
mutable_support_scalar_raw_u32: 0x3f4ccccd, mutable_support_scalar_raw_u32: 0x3f4ccccd,
young_company_support_scalar_raw_u32: 0x42580000, young_company_support_scalar_raw_u32: 0x42580000,
support_progress_word: 9, support_progress_word: 9,
@ -6376,6 +6378,7 @@ mod tests {
42, 42,
crate::RuntimeCompanyMarketState { crate::RuntimeCompanyMarketState {
outstanding_shares: 30_000, outstanding_shares: 30_000,
bond_count: 3,
mutable_support_scalar_raw_u32: 0x3f19999a, mutable_support_scalar_raw_u32: 0x3f19999a,
young_company_support_scalar_raw_u32: 0x42580000, young_company_support_scalar_raw_u32: 0x42580000,
support_progress_word: 8, support_progress_word: 8,

View file

@ -53,6 +53,8 @@ pub struct RuntimeCompanyMarketState {
#[serde(default)] #[serde(default)]
pub outstanding_shares: u32, pub outstanding_shares: u32,
#[serde(default)] #[serde(default)]
pub bond_count: u8,
#[serde(default)]
pub mutable_support_scalar_raw_u32: u32, pub mutable_support_scalar_raw_u32: u32,
#[serde(default)] #[serde(default)]
pub young_company_support_scalar_raw_u32: u32, pub young_company_support_scalar_raw_u32: u32,
@ -96,6 +98,7 @@ pub struct RuntimeCompanyMarketState {
pub struct RuntimeCompanyAnnualFinanceState { pub struct RuntimeCompanyAnnualFinanceState {
pub company_id: u32, pub company_id: u32,
pub outstanding_shares: u32, pub outstanding_shares: u32,
pub bond_count: u8,
pub assigned_share_pool: u32, pub assigned_share_pool: u32,
pub unassigned_share_pool: u32, pub unassigned_share_pool: u32,
#[serde(default)] #[serde(default)]
@ -352,6 +355,7 @@ pub enum RuntimeCompanyMetric {
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum RuntimeCompanyMarketMetric { pub enum RuntimeCompanyMarketMetric {
OutstandingShares, OutstandingShares,
BondCount,
AssignedSharePool, AssignedSharePool,
UnassignedSharePool, UnassignedSharePool,
CachedSharePrice, CachedSharePrice,
@ -1923,6 +1927,7 @@ pub fn runtime_company_annual_finance_state(
Some(RuntimeCompanyAnnualFinanceState { Some(RuntimeCompanyAnnualFinanceState {
company_id, company_id,
outstanding_shares: market_state.outstanding_shares, outstanding_shares: market_state.outstanding_shares,
bond_count: market_state.bond_count,
assigned_share_pool, assigned_share_pool,
unassigned_share_pool, unassigned_share_pool,
cached_share_price: rounded_cached_share_price_i64(market_state.cached_share_price_raw_u32), cached_share_price: rounded_cached_share_price_i64(market_state.cached_share_price_raw_u32),
@ -1953,6 +1958,7 @@ pub fn runtime_company_market_value(
RuntimeCompanyMarketMetric::OutstandingShares => { RuntimeCompanyMarketMetric::OutstandingShares => {
Some(annual_finance_state.outstanding_shares as i64) Some(annual_finance_state.outstanding_shares as i64)
} }
RuntimeCompanyMarketMetric::BondCount => Some(annual_finance_state.bond_count as i64),
RuntimeCompanyMarketMetric::AssignedSharePool => { RuntimeCompanyMarketMetric::AssignedSharePool => {
Some(annual_finance_state.assigned_share_pool as i64) Some(annual_finance_state.assigned_share_pool as i64)
} }
@ -4222,6 +4228,7 @@ mod tests {
4, 4,
RuntimeCompanyMarketState { RuntimeCompanyMarketState {
outstanding_shares: 20_000, outstanding_shares: 20_000,
bond_count: 3,
cached_share_price_raw_u32: 0x42200000, cached_share_price_raw_u32: 0x42200000,
chairman_salary_baseline: 24, chairman_salary_baseline: 24,
chairman_salary_current: 30, chairman_salary_current: 30,
@ -4247,6 +4254,7 @@ mod tests {
Some(RuntimeCompanyAnnualFinanceState { Some(RuntimeCompanyAnnualFinanceState {
company_id: 4, company_id: 4,
outstanding_shares: 20_000, outstanding_shares: 20_000,
bond_count: 3,
assigned_share_pool: 15_500, assigned_share_pool: 15_500,
unassigned_share_pool: 4_500, unassigned_share_pool: 4_500,
cached_share_price: Some(40), cached_share_price: Some(40),
@ -4344,6 +4352,7 @@ mod tests {
7, 7,
RuntimeCompanyMarketState { RuntimeCompanyMarketState {
outstanding_shares: 20_000, outstanding_shares: 20_000,
bond_count: 2,
cached_share_price_raw_u32: 0x42200000, cached_share_price_raw_u32: 0x42200000,
chairman_salary_baseline: 18, chairman_salary_baseline: 18,
chairman_salary_current: 27, chairman_salary_current: 27,
@ -4365,6 +4374,10 @@ mod tests {
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::OutstandingShares), runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::OutstandingShares),
Some(20_000) Some(20_000)
); );
assert_eq!(
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::BondCount),
Some(2)
);
assert_eq!( assert_eq!(
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::AssignedSharePool), runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::AssignedSharePool),
Some(12_000) Some(12_000)

View file

@ -3581,6 +3581,7 @@ fn parse_save_company_roster_probe(
record_offset + SAVE_COMPANY_RECORD_OUTSTANDING_SHARES_OFFSET, record_offset + SAVE_COMPANY_RECORD_OUTSTANDING_SHARES_OFFSET,
)?; )?;
let debt = parse_save_company_total_debt(bytes, record_offset)?; let debt = parse_save_company_total_debt(bytes, record_offset)?;
let bond_count = read_u8_at(bytes, record_offset + SAVE_COMPANY_RECORD_BOND_COUNT_OFFSET)?;
let available_track_laying_capacity = let available_track_laying_capacity =
parse_save_company_available_track_laying_capacity(bytes, record_offset)?; parse_save_company_available_track_laying_capacity(bytes, record_offset)?;
let mutable_support_scalar_raw_u32 = read_u32_at( let mutable_support_scalar_raw_u32 = read_u32_at(
@ -3694,6 +3695,7 @@ fn parse_save_company_roster_probe(
merger_cooldown_year, merger_cooldown_year,
market_state: Some(RuntimeCompanyMarketState { market_state: Some(RuntimeCompanyMarketState {
outstanding_shares, outstanding_shares,
bond_count,
mutable_support_scalar_raw_u32, mutable_support_scalar_raw_u32,
young_company_support_scalar_raw_u32, young_company_support_scalar_raw_u32,
support_progress_word, support_progress_word,

View file

@ -50,6 +50,7 @@ pub struct RuntimeSummary {
pub active_company_count: usize, pub active_company_count: usize,
pub company_market_state_owner_count: usize, pub company_market_state_owner_count: usize,
pub selected_company_outstanding_shares: Option<u32>, pub selected_company_outstanding_shares: Option<u32>,
pub selected_company_bond_count: Option<u8>,
pub selected_company_assigned_share_pool: Option<u32>, pub selected_company_assigned_share_pool: Option<u32>,
pub selected_company_unassigned_share_pool: Option<u32>, pub selected_company_unassigned_share_pool: Option<u32>,
pub selected_company_cached_share_price: Option<i64>, pub selected_company_cached_share_price: Option<i64>,
@ -258,6 +259,8 @@ impl RuntimeSummary {
company_market_state_owner_count: state.service_state.company_market_state.len(), company_market_state_owner_count: state.service_state.company_market_state.len(),
selected_company_outstanding_shares: selected_company_market_state selected_company_outstanding_shares: selected_company_market_state
.map(|market_state| market_state.outstanding_shares), .map(|market_state| market_state.outstanding_shares),
selected_company_bond_count: selected_company_market_state
.map(|market_state| market_state.bond_count),
selected_company_assigned_share_pool: selected_company_annual_finance_state selected_company_assigned_share_pool: selected_company_annual_finance_state
.as_ref() .as_ref()
.map(|finance_state| finance_state.assigned_share_pool), .map(|finance_state| finance_state.assigned_share_pool),
@ -1956,6 +1959,7 @@ mod tests {
1, 1,
crate::RuntimeCompanyMarketState { crate::RuntimeCompanyMarketState {
outstanding_shares: 20_000, outstanding_shares: 20_000,
bond_count: 2,
mutable_support_scalar_raw_u32: 0x3f800000, mutable_support_scalar_raw_u32: 0x3f800000,
young_company_support_scalar_raw_u32: 0x42340000, young_company_support_scalar_raw_u32: 0x42340000,
support_progress_word: 12, support_progress_word: 12,
@ -2023,6 +2027,7 @@ mod tests {
let summary = RuntimeSummary::from_state(&state); let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.company_market_state_owner_count, 1); assert_eq!(summary.company_market_state_owner_count, 1);
assert_eq!(summary.selected_company_outstanding_shares, Some(20_000)); assert_eq!(summary.selected_company_outstanding_shares, Some(20_000));
assert_eq!(summary.selected_company_bond_count, Some(2));
assert_eq!(summary.selected_company_assigned_share_pool, Some(5_000)); assert_eq!(summary.selected_company_assigned_share_pool, Some(5_000));
assert_eq!(summary.selected_company_unassigned_share_pool, Some(15_000)); assert_eq!(summary.selected_company_unassigned_share_pool, Some(15_000));
assert_eq!(summary.selected_company_cached_share_price, Some(40)); assert_eq!(summary.selected_company_cached_share_price, Some(40));

View file

@ -126,7 +126,8 @@ The highest-value next passes are now:
closure can target a broader owned restore-state window; the same annual-finance state now also closure can target a broader owned restore-state window; the same annual-finance state now also
feeds a shared company market reader for stock-capital, salary, bonus, and issue-calendar values, feeds a shared company market reader for stock-capital, salary, bonus, and issue-calendar values,
and now derives elapsed years since founding, last dividend, and last bankruptcy for later annual and now derives elapsed years since founding, last dividend, and last bankruptcy for later annual
finance-policy rehosting finance-policy rehosting; live bond-slot count now travels through that same owned annual-finance
state for the stock-capital branch gate
- the project rule on the remaining closure work is now explicit too: when one runtime-facing field - 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 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 instead of guessing another derived leaf field from neighboring raw offsets

View file

@ -216,7 +216,9 @@ now also drives a shared company market reader seam for stock-capital, salary, b
issue-calendar values, which is a better base for shellless finance simulation than summary-only issue-calendar values, which is a better base for shellless finance simulation than summary-only
helpers. That same owned annual-finance state now also derives elapsed years since founding, last helpers. That same owned annual-finance state now also derives elapsed years since founding, last
dividend, and last bankruptcy from the runtime calendar, which lines up directly with the grounded dividend, and last bankruptcy from the runtime calendar, which lines up directly with the grounded
annual finance-policy gates in the atlas. annual finance-policy gates in the atlas. Live bond-slot count now also flows through that same
owned company market and annual-finance state, matching the stock-capital branch gate that needs
at least two live bonds.
## Why This Boundary ## Why This Boundary