Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/agent-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,13 @@ local `--spec-dir`.
Extensions can wrap a factory in `TransportExtension` to declare additional
sources and ordered checkpoints. Source names must be new; skeleton predecessor
sets must stay identical except for explicit `package_inputs` artifact edges
from extension nodes to a terminal `transport.package@1` receipt. Other skeleton
nodes cannot gain predecessors. Checkpoints run after calibration and before export,
and must not depend on the exported dataset. `transport_rules_node` supplies
from extension nodes to a terminal `transport.package@1` receipt and the
battery evidence edges described below. Checkpoints run after calibration and before export,
and must not depend on the exported dataset. Explicit `gate_inputs` artifact
edges may attach required extension diagnostics to a skeleton
`gates.battery@1` node; its existing report edge governs export permission.
Only package receipts and battery nodes may gain these declared artifact
predecessors. `transport_rules_node` supplies
the prepared engine reference and period from the binding, so extensions do
not repeat period values.
An optional `entitlement_graph.json` legacy resource installs the entitlement
Expand Down
3 changes: 2 additions & 1 deletion docs/concept-coverage/axiom-be.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Concept coverage: axiom:be

Engine version `b105e2b3a3086ddd2de447d58a9b951346870dd1`; concept schema `d824f5e97d58`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.
Engine version `b105e2b3a3086ddd2de447d58a9b951346870dd1`; concept schema `5a55669d0447`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.

- Engine inputs: 1867
- Fed by a concept: 105
Expand Down Expand Up @@ -46,6 +46,7 @@ Engine version `b105e2b3a3086ddd2de447d58a9b951346870dd1`; concept schema `d824f
| `fact:person.enrolled_full_time` | rulespec-be has no input that tests full-time enrollment. The full-time wording in non-test rule text concerns work regimes (parental leave, the work bonus, unemployment admission, the Flemish jobbonus). The one exception is a Flemish school-allowance parameter citing 'voltijds secundair onderwijs', and that module selects it by education level alone. The student statuses the tree does take are supplied legal statuses, and the rules that consume them contain no full-time test: belgium_self_employed_is_student (RD 38 art. 12bis) and the Child-entity family-benefit training and 'qualifying' flags. |
| `fact:person.take_up_seed` | rulespec-be computes legal entitlements and has no take-up or participation input. Its only claim-type inputs are eligibility conditions or elections, not decisions to take up the program the rule computes: belgium_social_integration_social_benefit_rights_asserted (a RIS art. 3-4 condition), brussels_apa_required_other_benefit_rights_claimed (an APA eligibility conjunct), and belgium_pit_article_1458_pension_savings_reduction_claimed (a non-cumulation election against the art. 145/7 reduction that also needs pension-savings payments). |
| `fact:household.mortgage_principal` | rulespec-be at b105e2b3 has no input for mortgage capital repayments. The only housing-loan inputs are the interest deductions belgium_social_integration_eligible_annual_mortgage_interest_on_property (RIS art. 25 §4) and brussels_apa_eligible_annual_mortgage_interest (APA art. 15), which this mapping feeds from mortgage_interest. No non-test rule text mentions capital repayment, and the PIT reductions module takes no loan input. |
| `fact:household.source_household_id` | Original donor household lineage is build provenance and weight diagnostic support, not a rulespec-be legal input. |

## Inputs no concept covers

Expand Down
3 changes: 2 additions & 1 deletion docs/concept-coverage/axiom-nz.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Concept coverage: axiom:nz

Engine version `6fe181fc4c65763150fe97501ef3443774e64869`; concept schema `d824f5e97d58`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.
Engine version `6fe181fc4c65763150fe97501ef3443774e64869`; concept schema `5a55669d0447`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.

- Engine inputs: 668
- Fed by a concept: 89
Expand Down Expand Up @@ -46,6 +46,7 @@ Engine version `6fe181fc4c65763150fe97501ef3443774e64869`; concept schema `d824f
| `fact:person.weeks_worked` | rulespec-nz at 6fe181f has no input the concept determines: the closest, in_work_tax_credit_weekly_periods (Family, income_tax/family_scheme/tax_credits.yaml, s MD 10(2)), counts weeks in which the person or their partner meets the earner requirement, which needs the union of two partners' work weeks that no group rule gives (reference_member drops a working partner; sum_over_members double-counts and adds children's weeks), and minimum_family_tax_credit_weekly_periods and minimum_family_full_time_earner_weeks count only weeks as a full-time earner. |
| `fact:person.educational_attainment` | rulespec-nz at 6fe181f has no input for completed education: no rule or input name mentions a qualification, degree, diploma or attainment level; the education inputs are current enrollment or school attendance (this mapping binds some of them to education_enrollment and enrolled_full_time); and young_person_is_study_ready is what youth_young_parent_payment/core.yaml calls an agency-adjudicated composite input (s 50). |
| `fact:household.property_tax` | The only rates input, rr_rates_payable_before_rebate (Person) in statutes/rates_rebates/rates_rebate.yaml, cannot be bound at 6fe181f, because the dense engine could not compile that module and nz.json lists it only under cli_walk_inputs, which the adapter's surface loader does not read; once the module compiles, allocate_to_reference_person of property_tax is the candidate (approximate, because the ratepayer need not be the reference person). |
| `fact:household.source_household_id` | Original donor household lineage is build provenance and weight diagnostic support, not a rulespec-nz legal input. |

## Inputs no concept covers

Expand Down
3 changes: 2 additions & 1 deletion docs/concept-coverage/policyengine-uk.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Concept coverage: policyengine-uk

Engine version `2.122.2`; concept schema `d824f5e97d58`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.
Engine version `2.122.2`; concept schema `5a55669d0447`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.

- Engine inputs: 285
- Fed by a concept: 40
Expand Down Expand Up @@ -46,6 +46,7 @@ Engine version `2.122.2`; concept schema `d824f5e97d58`. Generated by `tools/ref
| `fact:household.reference_person_id` | is_household_head is formula-owned (the oldest member). The UK build overrides it with the FRS household reference person (frs_spine.py), an override the loader accepts, but it is not an input, so the mapping does not target it. Every housing input is household-level, so nothing is allocated to the reference person. |
| `fact:person.liquid_financial_assets` | policyengine-uk holds financial wealth on the household: savings ('Household liquid savings'), corporate_wealth ('Wealth held in corporations directly or through investment funds'), gross_financial_wealth and net_financial_wealth are household inputs, and no transform puts a person amount on a household input. Its person-level GBP stock inputs are student_loan_balance, a debt; car_list_price, the price vehicle excise duty's expensive-car supplement tests; and lifetime_isa_balance ('Current value of the person's Lifetime ISAs, cash and stocks and shares together'), one savings wrapper, which the engine documents as already inside gross_financial_wealth and net_financial_wealth. savings and corporate_wealth are two of Universal Credit's capital sources (gov.dwp.universal_credit.means_test.capital.sources), and lifetime_isa_countable_capital, the Lifetime ISA at its surrender value, is its one person-level source (capital.person_sources). uc_reported_capital (benefit unit; 'Claimant-level capital for Universal Credit when household-level asset data cannot be attributed across multiple benefit units', default -1) is Universal Credit capital: when it is zero or more, uc_assessable_capital takes it in place of both the household-capital proxy it otherwise sums from the household sources, net of capital other benefit units report, and apportions by claimant and partner count, and the person-level sources of the unit's claimant and partner, so feeding it would be a modelling choice for a UK build, not a mapping of this concept. |
| `fact:person.public_pension_income` | The State Pension is computed from state_pension_reported, which is formula-owned: the loader accepts it as an override, but it is not an input. |
| `fact:household.source_household_id` | Original donor household lineage is build provenance and weight diagnostic support, not a policyengine-uk rules input. |

## Inputs no concept covers

Expand Down
3 changes: 2 additions & 1 deletion docs/concept-coverage/policyengine-us.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Concept coverage: policyengine-us

Engine version `2.2.1`; concept schema `d824f5e97d58`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.
Engine version `2.2.1`; concept schema `5a55669d0447`. Generated by `tools/refresh_concept_coverage.py`; do not edit by hand.

- Engine inputs: 926
- Fed by a concept: 55
Expand Down Expand Up @@ -46,6 +46,7 @@ Engine version `2.2.1`; concept schema `d824f5e97d58`. Generated by `tools/refre
| Concept | Reason |
|---|---|
| `fact:person.liquid_financial_assets` | policyengine-us splits this stock across three person inputs, which the populace-us donor H5 also carries as person columns. Their engine documentation: bank_account_assets ('Value of checking, savings, and money market accounts. Imputed from SIPP TVAL_BANK.'), stock_assets ('Value of stocks and mutual funds. Imputed from SIPP TVAL_STMF.') and bond_assets ('Value of bonds and government securities. Imputed from SIPP TVAL_BOND.'). All three uprate with CPI-U (gov.bls.cpi.cpi_u), the concept's consumer-price index family. The documentation names no term deposits. In the donor (microcosm.build.us_runtime.scf_wealth and sipp_financial_assets), each household takes its whole three-column vector from either the SCF or the SIPP, about half each, and the vector sits on the member with the lowest CPS line number (the householder is line 1), with every other member at zero. SCF-sourced households carry a draw of an SCF family-unit total, whose bank column comes from SCF liq (checking, savings, money-market and call accounts) and so leaves out term deposits. SIPP-sourced households carry a draw from a model trained on individual SIPP holdings (December person records, each with that person's own TVAL_BANK, TVAL_STMF and TVAL_BOND), whose bank leaf includes certificates of deposit: its quality screen reads the SIPP CD value allocation flags (AJSCDVAL, AJOCDVAL, AOCDVAL). Neither half holds each owner's share. spm_unit_assets (SPM unit; read by the federal CCDF asset test is_ccdf_asset_eligible, the Massachusetts, Indiana, Iowa and Texas child-care asset tests ma_ccfa_asset_eligible, in_ccdf_asset_eligible, ia_cca_asset_eligible and tx_ccs_asset_eligible, and Illinois's HBI resource test il_hbi_resource_eligible) is a unit stock the engine defines only by its label 'SPM unit assets', so feeding it would be a modelling choice. No transform here splits one amount across three inputs: a share pair splits it in two, and a fraction is never decoded. So decode cannot recover the concept from these inputs, and encoding it waits for a reviewed three-way split. |
| `fact:household.source_household_id` | Original donor household lineage is build provenance and weight diagnostic support, not a policyengine-us rules input. |

## Inputs no concept covers

Expand Down
10 changes: 8 additions & 2 deletions docs/concept-schema-transport-adr.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ on built benefit units; the other three mappings list it as unmapped with a
reason. A scale, sum, scaled sum, share or fraction now computes from annual
flows only (invariant 11), so none of them can rescale the stock, add it to a
year's income, or split it.
**Amended 2026-10-10:** schema version 3 adds original
`household.source_household_id` lineage for donor support diagnostics. The
reader scopes explicit raw household identifiers by source year and carries
the same key across support clones and their benefit units. Rules mappings
leave this provenance concept unmapped.

## Context

Expand All @@ -42,7 +47,7 @@ working through the same layer.
### 1. Primitive facts are the neutral layer

`microcosm.frame.concepts` declares the record-level facts a household survey
observes and that keep their meaning across countries. There are 29, on two
observes and that keep their meaning across countries. There are 30, on two
entities. Engine group entities (tax units, benefit units, SPM units,
families) are engine constructs built from relationships. Today the US unit
operator builds them from raw CPS roster columns, and the UK adapter requires
Expand All @@ -52,6 +57,7 @@ not yet built from them.

| Topic | Concepts |
|---|---|
| Source lineage | household `source_household_id` |
| Demography | `age`, `sex`, `legal_marital_status` |
| Relationships | `partner_person_id`, `parent_1_person_id`, `parent_2_person_id`, household `reference_person_id` |
| Labour income | `employment_income`, `nonfarm_self_employment_income`, `farm_self_employment_income` |
Expand All @@ -66,7 +72,7 @@ not yet built from them.
Each concept declares:

- **Unit.** Years, base currency, hours per week, weeks, category, boolean,
person id or unit interval.
person id, source id or unit interval.
- **Period semantics.** The kernel's `year`, `month` or `point`, plus what the
value measures over it: an annual flow, a state at the reference date, a usual
rate over the weeks worked, or persistent state.
Expand Down
2 changes: 2 additions & 0 deletions packages/microcosm-build/src/microcosm/build/country_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@
"aggregate_admin",
"area_support",
"calibration_reference_coverage",
"cell_support",
"cell_support_target",
"cgt_projection_entrants",
"column_implication",
"degenerate_release_surface",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"household_reference_person": "reference_person_id",
"citation": "packages/microcosm-frame/src/microcosm/frame/concepts.py:880-919"
},
"source_household_lineage": {
"concept": "fact:household.source_household_id",
"unit_column": "family.family_source_household_id",
"rule": "Each unit inherits its household's exact original-source key. The donor reader scopes raw source_household_id by source_year, merging support clones across channels; no row-order or support-row-id fallback is permitted."
},
"composition": [
{
"member": "adult",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"family_weight"
],
"optional": [
"source_household_id",
"family_source_household_id",
"age",
"sex",
"region_code",
Expand Down
Loading
Loading