Changelog¶
All notable changes to this project will be documented here.
Format follows Keep a Changelog. Versions follow Semantic Versioning.
[Unreleased]¶
Fixed¶
Flagged cleanup after the docs pass (2026-09-12)
- eoh dashboard no longer invents its accounts. The ledger, the Trust and the
EOH totals were built from literals (destroyed = 0.85 × created, expenditure =
0.90 × earnings, total EOH = population × base × 1.5), so Conditions I and III
passed by construction. EOH now comes from the pipeline and the ledger and
Trust from one simulated period on the same frame; the certified competency
share, which nothing tracks, is declared and printed (--certified-fraction).
No status changed at any reference ε.
- run_simulation reported a 2.10 multiplier for periods it minted at
simulate_period's own default.
- corridor_is_usable(cadence="continuous") still described the cadence as
undecided; its note now reads the crossover and the analogue disagreement live.
- API pages for prices, multipliers, trajectory, conditions, simulation, EOH
generation and fulfilment corrected against the docstrings; knowledge EOH no
longer claimed to become dominant (personal stays the largest domain), and
personal registration no longer claimed to approach 1.0.
- guf_framework.md describes the shipped per-parcel term and the ×100 use-rate
scaling beside the NLSA specification.
Changed¶
The signed-off transparency pass reaches the front pages (2026-09-12)
- overview.md, design_principles.md, three_economies.md and the arc
waypoints now carry the positions adopted on 2026-08-15: ε → 1 as a limit,
prices as floor prices, and currency that records and shows its work rather
than measuring value. Design Principle 8 no longer says a green dashboard means
the system works.
- guf_framework.md gives the shipped fee (Ψ retired, monotone in ε) beside the
NLSA bell in §4.1 and §4.4, and labels the worked example as the published
NLSA form.
Added¶
The anchor comparison is published, and the docs are gated (2026-09-12)
- docs/theory/anchor_comparison.md — What Anchors a Unit of Account, published
as work in progress beside Prior Art. It quotes shapes where a figure is
calibration and values only where a figure is structural;
tests/test_anchor_page_figures.py reads the published page and checks every
structural statement against utils/anchor_page_figures.py.
- tests/test_doc_examples.py — every Python block in README.md and docs/
runs, every eoh_cli.py example parses, and every API signature heading names
real parameters. 34 of 54 published examples and 95 signature headings had
gone stale with nothing checking them. Template blocks and placeholder CLI
lines are ratcheted.
- scenarios.collective.collective_snapshot() accepts available_labor_eoh and
rationing, and forwards the state's own deferred_ecological,
knowledge_complexity and monitoring_capability. The institutional entry
point could not previously verify fulfilment against labour at all, so every
snapshot measured demand. Blast radius on a default state: zero.
The tag scheme: CHOSEN split into bounded / placeholder / normative (2026-08-09)
- One tag was covering three epistemic states. It made the calibration set read as
83% guesswork while hiding which constants are the real debts, and it filed
charter decisions under "awaiting measurement" — a category error, since no dataset
settles what fraction of an estate should pass to heirs.
- bounded (14) — picked inside a measured band; band: and errs: are required
and gated, so "bounded" cannot be a free upgrade over placeholder. errs opens
with HIGH / LOW / NEITHER / WITHHELD, the last a real epistemic state here.
- placeholder (106) — nothing constrains it yet. The actionable debt.
- normative (60) — a decision. Requires decided_by:, may carry precedent:, and
is forbidden a resolves_by: — the forbidding is the point.
- The eight CANONICAL_* arc constants became convention: an ideal-arc reference
frame, whose own pointer already read "nothing, and by design".
- The honest headline: debt is 52.4%, not 83.3% — grounded 49 (21.4%), bounded 14
(6.1%), placeholder 106 (46.3%), normative 60 (26.2%). eoh provenance check now
prints this as a "Where the model stands" table via debt_summary().
- Of the 14 bounded picks 7 err LOW, and for DEP_RATE, THERMAL_F_GHG and the
GOVERNANCE_IRR_* pair low is the unsafe direction — it flatters solvency,
overstates the thermal allowance, and sets the assessment gate below the
conventional κ bar. Each records that on its own line.
- CDR_LABOR_HOURS_PER_TONNE → measured (Tier D): one plant's staffing disclosure
is a measurement with n=1, and it now matches GUF_ECO_KAPPA_CARBON.
Two constants revalued (2026-08-09, author decisions)
- RECAL_FOUNDING_LABOR_HOURS 1,000 → 666.67, and bound to PERSONAL_EOH_BASE
via the new RECAL_FOUNDING_FRACTION = 2/3. The reprice had silently turned
"two-thirds of the base" into the whole of it — a founder with nothing left to live
on. Blast radius measured: the labour arm lengthens exactly 1.5× (t_labor 1.80 →
2.70 yr at ε=0, worst 2.85 across the arc), the three-channel exit invariant holds
at every arc point, and the channel order is unchanged. TestFoundingLabourArm now
anchors the mechanism — nothing had been exercising the labour arm's timing, which
is why a 1.5× drift was invisible.
- GUF_ECO_KAPPA_CARBON 2.750 → 0.6, adopting CDR_LABOR_HOURS_PER_TONNE as the
better-sourced of two figures for the same physical quantity. Bound by test rather
than expression (forward reference), so either side moving alone fails. Left open
and pinned: whether CDR_GROSS_REMOVAL_FACTOR belongs in this path.
Provenance coverage closed and gated (2026-08-09)
- utils/provenance.py + utils/provenance_cmd.py — inline provenance tag blocks in
data.py are parsed from source, checked against the tag scheme, and rendered as the
shipped audit CSV and the generated tables in docs/parameter_provenance.md.
CLI: eoh provenance check | csv | table | doc.
- hours_eoh/reference/data/constant_provenance.csv — generated, one row per
data.py constant (value, units, tag, tier, form, block, resolves_by, note), so a
public audit needs no Python. Packaged via the existing hours_eoh.reference data glob.
- All 229 data.py constants now carry an inline tag block, up from an effective 3.
101 constants (44%) previously appeared nowhere in the provenance doc, 51 of them the
entire GUF block. Nine doc tables were still on the retired binary
Kind = Physics | Calibration.
- tests/test_provenance.py — 69 tests. Parser behaviour is pinned against synthetic
source; the coverage gate runs against the real data.py with no allowlist,
and fails on an untagged constant, a stale or unmatched tag block, a retired or unknown
tag, a missing epistemic pointer, a bounded constant with no band or no error
direction, a normative constant with no decider or one claiming a resolves_by,
missing units, a misapplied tier, a stale audit CSV, stale generated doc tables, or a
block with no doc home. Each was verified to bite by breaking it and reverting.
- tier (A–D) formalised as a sub-qualifier rather than a rival scheme, matching what
the thermal layer already wrote; it applies only where there is a source to grade.
convention promoted to a declared sub-label. The ad-hoc Physics-adjacent tag is
retired, along with CHOSEN itself (see the split above).
Changed¶
Provenance doc: tables generated, prose hand-written
- Every constant table in docs/parameter_provenance.md now sits inside a
<!-- provenance:table --> region rendered from data.py. The prose around them — where
the epistemic argument lives — is untouched and stays hand-written. New sections for
Ground Use Fee, dashboard thresholds, capital lifecycle, TEH destruction, human capital
and multiplier governance, none of which had one.
- No calibration constant changed. Verified constant-by-constant against the previous
commit: 228 compared, 0 value differences.
- Only 2 of 229 constants are physics — applying the scheme's own demanding
definition honestly leaves A_EARTH_M2 and SIGMA_SB and nothing else. The 190 that
first became CHOSEN were then split (see above), because one tag covering three
epistemic states was itself obscuring the picture.
Fixed¶
Four documentation drifts, found by the migration
- KNOWLEDGE_EOH_BASE — doc said 490,107,421; the shipped value has been
381,962,855.27 since the ε_ref fixed-point re-anchor.
- CARE_SIGMOID_DEFAULTS — doc said start_share 0.30 / inflection 0.55 against the
shipped 0.05 / 0.45; it had never matched the code.
- Membership min-hours thresholds printed as 750 / 1500 h/yr and per-capita personal EOH
as 2,213 — both are products of PERSONAL_EOH_BASE and went stale at the
1,500 → 1,000 reprice. Now 500 / 1,000 and 1,475. A curated test pins these derived
products, because no value-equality check can see a number restated in a sentence.
- RECAL_FOUNDING_LABOR_HOURS was documented as "≈ 2/3 of PERSONAL_EOH_BASE" while the
reprice had made it 100% of it. Decided and fixed — see "Two constants revalued"
above.
Findings (reported, not resolved)¶
- NLSA cites this framework's own document. All 51 GUF constants attribute to "NLSA
Technical Manual TM-0042", whose own header reads "Based on NLSA from HOURSFramework".
Equation numbers now appear only under
form:, neverresolves_by:— they establish an asserted form, not external evidence for a value. GUF_ECO_KAPPA_CARBON(2.750 TEH/tCO₂e) andCDR_LABOR_HOURS_PER_TONNE(0.6 h/t) were the same quantity from two layers — a 4.58× disagreement, now RECONCILED (see above). Still open:DEP_RATE0.045 vsFORMATION_DEPRECIATION_RATE0.05, andCONTESTABILITY_CAPITAL_YIELD_RATE0.10 vs the 0.20 derivable fromRECAL_CAPITAL_OUTPUT_RATIOandFORMATION_DEPRECIATION_RATE.- Four constants are calibrated to a target and now say so:
GUF_USE_*,DEFAULT_SEGMENTS,TRUST_BASE_TEH,CAPITAL_MACHINE_PROFILES— the_ECOLOGICAL_SPIKE_INTENSITYpattern the 2026-08-05 pass named but did not sweep for. LEVY_SUFFICIENCY_WARNcannot fire on the shipped configuration: it warns below 2% guarantee coverage, andSUFF_LEVY_RATEdelivers ≈2% at canonical defaults._ECOLOGICAL_SPIKE_INTENSITYlives incore/eoh_generation.py, notdata.py, so the gate cannot see a constant the retag log covers — a standing violation of the no-anonymous-constants invariant.- Residual the gate does not close: free prose can still go stale. The curated derived-product test covers where the reprice drift actually hid; a narrative paragraph that goes stale in a way no field captures remains a human problem, and saying so is better than implying the test closes it.
Federation contestability closure (reconciliation §8.7 — research tier)
- research/coasean.py Phase 4 — two-tier Trust: merge_collectives() and
split_collective() boundary events with indivisible-reserve escheat (§8.7c) and
TEH-conservation postconditions (§8.7d); simulate_federation(commons=True) tracks a
federation commons funded by a levy tithe (COASEAN_COMMONS_TITHE, Italian Law 59/1992
precedent) plus consolidation escheats, and records per-collective χ each period
(chi_min, chi_marginal_min, chi_worst_collective, chi_status_worst,
commons_balance, commons_floor_coverage). τ counts both tiers. Defaults are
byte-identical to Phase 3.
- research/contestability.py — portable_endowment_federated() (two-tier P: the floor
is federation-guaranteed and never vests; the dividend claim is per-collective),
exit_value() (the floor crosses collective boundaries at par; only the capital
account converts at the exchange rate), contestability_margin_federated().
Tenure is federation-wide (§8.7b): moving collectives never resets vesting.
- research/membership.py — MembershipTerms + contestability_audit(): the §8.7e
math/contract line. Admission cost adds to K_entry; exit notice, minimum hours,
vesting length, and dividend retention are audited against MEMBERSHIP_* thresholds.
- CLI: eoh coasean simulate gains --dynamics --g-priv --levy-rate --commons
--commons-tithe --regime; new eoh contestability audit subcommand.
- Honest adversarial findings at defaults (reported, not tuned): commons floor coverage
is tiny at a 3% tithe, and consolidation escheat migrates trust from collective
dividends to the commons across the arc, so the worst marginal χ worsens toward ε→1.
Contestability closure mechanisms (proposed §8.8 — research tier, pending author
sign-off; see notes/contestability-closure-proposal.md)
- Answers the Phase 4 adversarial findings. Root-cause diagnosis: (1) the commons was
dividend-inert, so §8.7c escheat drained tenure-vested dividends into a fund paying
no one; (2) the marginal (tenure-0) member holds no capital claim, so no levy
schedule can close χ_marginal; (3) the static levy base ε·K·yield understates
machine output ~12× at high ε (an ε=0-era capital calibration held fixed);
(4) χ compares an annual endowment flow to a one-time founding stock.
- M1 — universal commons dividend: portable_endowment_federated(...,
commons_balance) pays the commons yield per capita UNVESTED (Alaska Permanent
Fund precedent); escheat becomes a stabilizer — consolidation moves capital from
tenure-gated collective dividends into the universal tier.
- M2 — entry underwriting: entry_underwriting() + commons_seed_required();
the commons capitalizes new collectives' trusts (stays commonized, §8.7c).
Combined invariant: exit_financeable ⇔ χ_marginal ≥ 1 OR entry_capacity ≥ 1.
With a seed of ~1.8e7 TEH (~0.05% of the Trust base) the combined invariant holds
at EVERY period of the canonical adversarial arc (asserted in tests) — while
χ_marginal alone stays honestly CRIT at high ε (commons-financed, not
self-financed exit).
- M3 — physically-consistent levy base: machine_output_teh(ε) = ε·total_eoh(ε);
levy_schedule_for_chi(levy_base="machine_output"). Growth steps of the schedule
remain infeasible — M3 removes the calibration artifact, it does not manufacture
feasibility.
- simulate_federation(commons_dividend=True, commons_start=...) wires M1+M2 into
the federation arc (commons_dividend_paid, entry_capacity, exit_financeable);
contestability_audit(commons_dividend=, underwriting_policy=) audits terms
against the combined invariant (CRIT → WARN waiver is opt-in; §8.7e defaults
unchanged). New constants CONTESTABILITY_MIN_VIABLE_POPULATION (uncalibrated
placeholder, documented as such) and CONTESTABILITY_UNDERWRITE_FRACTION.
- CLI: coasean simulate --commons-dividend --commons-start; contestability levy
--levy-base; contestability audit --commons-dividend --underwriting-policy.
- All defaults preserve §8.7 behavior float-exact; 38 new tests (1595 total).
Recalibration prototype (proposed §8.9 — research tier; adopted-in-principle by the
author 2026-07-26, formal reconciliation-doc edit pending)
- research/recalibration.py — resolves the three §8.8 "honest remainders" at their
causes. RC4 fix: the flow/stock χ is replaced by time-to-finance-exit
(exit_financing(), invariant t_exit ≤ RECAL_EXIT_HORIZON_YEARS = one vesting
period) and a genuine accumulating §8.7b capital account (capital_account_stock(),
Mondragon internal-account precedent, zero-interest per Condition III). Open item 3
fix: capital_stock_epsilon() grows the stock with machine output
(K(ε) = K₀ + ν·Y(ε), ν = Piketty's β ≈ 4) and the commons OWNS share φ(ε) of it
(Meade social-dividend model), so τ = φ ≤ 1 by construction and dτ/dε ≥ 0
(Piketty inversion) is structural, not levy-contingent. The dividend is the commons'
capital income net of share acquisition (commons_income_statement()) — 0 at ε=0,
≈1,873 TEH/person·yr at ε=0.99: funded by measured machine output, not a promise.
- Self-financing dropped as the test (author decision): exit finance has three
physical channels — own labor at low ε (the floor feeds the founders while they
build), commons underwriting through the mid-arc trough (Caja Laboral / Marcora
precedent), dividend savings at high ε. recalibrated_arc() shows the combined
invariant holding at EVERY arc point in the adversarial regime, with the channel
arcing labor → underwritten → self (asserted in tests).
- Honest findings at defaults (reported, not tuned): share acquisition out of commons
income is infeasible for ε ≲ 0.15 (the initial endowment φ₀·K₀ and human-era
fiscal levies must carry the early arc); endogenous private-capital growth turns
negative past ε ≈ 0.5 — the §8.2 commonization made visible instead of assumed
away as a fixed g_priv.
- trust_required_for_chi() and levy_schedule_for_chi() marked SUPERSEDED
(retained unchanged as documented negative results: the trust-growth path cannot
close bare χ — which is why underwriting exists).
- New constants (all provenance-documented, placeholders flagged):
RECAL_CAPITAL_OUTPUT_RATIO, RECAL_EPSILON_RATE_PER_YEAR,
RECAL_FOUNDING_LABOR_HOURS, RECAL_EXIT_HORIZON_YEARS,
RECAL_ACCOUNT_CREDIT_SHARE.
- CLI: eoh contestability recal — the §8.9 arc table. 62 new tests (1657 total).
§8.9b — charter-formation doctrine (research tier; doctrine bundle agreed with the
author 2026-07-26)
- phi_policy on the recalibration module: "dilution" (new default doctrine),
"target" (§8.9a purchase model, kept as the regression anchor), "escalated".
- Charter formation (A3): the commons' share attaches to NEW capital at
commissioning as a federation charter condition (resource-license / Georgist
model) — formation_share_required() gives the per-ε charter share s(ε)
(≈ 0.17 early, crossing 1 at ε ≈ 0.48). Nothing is purchased, so the §8.9a
early-arc funding gap disappears and the dividend is the full φ·Y (self-financed
exit from ε ≈ 0.30 vs 0.59 under §8.9a). formation_levy_rate() quantifies the
compensated bridge (≈ 1% of labor-era output, sunsetting by ε ≈ 0.2).
- Dilution ratchet (B2): private capital is NEVER sold down — it follows a
running-max ratchet (rises while s ≤ 1, then flat). Honest cost, reported not
tuned: φ caps at ≈ 0.66–0.68 by ε = 0.99 (target 0.99); the exit invariant
still holds at every arc point with D ≈ 1,600 TEH/person·yr.
- Escalation clause (B3): escalation_trigger() — adversarial regime observed AND
(entry capacity < RECAL_ESCALATION_CAPACITY_FLOOR or invariant failing) →
the charter takes all new formation (s = 1) and capital-estate escheat rises to
RECAL_ESCALATION_ESTATE_SHARE. The trigger LATCHES in the arc; at canonical
defaults it NEVER fires (asserted in tests; forced firing tested at a 40×
founding cohort, lifting φ to ≈ 0.86 at ε = 0.99).
- Generational conversion (B4): estate_conversion_flow() — capital estates
escheat at RECAL_ESTATE_CAPITAL_ESCHEAT_SHARE (0.15 = ESTATE_LEVY_FRACTION:
the D5 doctrine extended to capital, not a new rule). Honest finding: mortality
speed is slow (half-life ≈ 69 yr even at full escheat) — φ → target is
asymptotic over generations; §8.2's "φ must be ABLE to → 1" survives as an
asymptotic capability, and the exit invariant never depends on it.
- recalibrated_arc() path-integrates the capital split (TEH-conservation
asserted); rows gain phi_target, cap_binding, s_required, escalation_active,
private_capital_delta_per_year (the absolute-flow reporting fix — a rate on a
vanishing base was theatrical). Open item, flagged: the charter share is an
implicit tax on private capital formation; the investment-disincentive feedback
on K(ε) is not simulated.
- CLI: contestability recal --phi-policy --estate-escheat --min-viable-population;
s_req/ΔKpriv columns, cap-binding and escalation markers. 79 new tests (1736
total).
§8.9c — formation feedback (research tier): who actually builds K(ε)
- research/formation.py closes the investment-disincentive circularity §8.9b
flagged open. Formation is FINANCED or it does not happen: private supply
f(s) falls linearly as the charter share cuts the net return
r_priv = (1−s)(1/ν−δ); the commons co-funds from net income per a priority
policy; ε is DERIVED from the capital actually formed (aggregate inversion of
the module's own physics; typed-capital integration via core/civilization.py
is the follow-up).
- Two corrections found in planning, now in the accounting: (1) the §8.9b
funding hole — in the cap region s = 1 attracts zero private funding, so the
commons pays for ALL formation there; (2) replacement — the commons must
replace its own worn stock (δ·T_K ≈ a 20–24% dividend haircut);
commons_income_statement(net_of_replacement=True) reports it (default False
preserves published §8.9b gross figures).
- Null anchor (charter share pinned 0): reproduces the canonical ~50-yr arc
pace exactly — the baseline every feedback effect is measured against.
- VERDICTS (honest, asserted in tests): share-first priority holds the canonical
pace with ZERO delay — the feedback costs the arc nothing in time, but the
dividend pays for it (D ≈ 113 vs static 302 at ε ≈ 0.4; self-financing onset
moves from ε ≈ 0.30 to ε ≈ 0.86, underwriting carries the transition).
Dividend-first never stalls but CRAWLS: ε ≈ 0.60 after 120 years, never
completing. The exit invariant holds at every simulated year under BOTH
priorities and even in the fiat counterfactual — capacity does not depend on
the dividend.
- THE CONDITION III FINDING: zero interest is the doctrine's structural ally.
The incentive-compatible charter share is s* = 1 − r_full/r_gross = 0.50 at
zero-interest returns vs ≈ 0.10 at fiat-like returns; in the fiat
counterfactual the commons must drive the dividend to literally ZERO mid-arc
to hold pace, where the zero-interest world never does. The framework's
pieces reinforce each other, quantified.
- New constants (provenance-documented, flagged): FORMATION_DEPRECIATION_RATE
(from CAPITAL_MACHINE_PROFILES design lives), FORMATION_HURDLE_RATE_MIN,
FORMATION_FULL_SUPPLY_RATE. CLI: contestability formation --priority
--hurdle --full-supply --escalation --charter-share. 39 new tests (1775
total).
Collective land-inventory system (hours_eoh/land/)
- collective.py — Standard parcel schema and batch GUF calculator for a collective land
inventory. compute_collective_guf(parcels, epsilon, median_income) loops all parcels through
ground_use_fee(), applies soil-health credits, review-cycle caps, and income-linked subsidies
per parcel, then aggregates via guf_trust_inflow(). Schema maps directly to geo-data pipeline
column names for zero-friction integration with GeoJSON/CSV sources.
- collective.make_urban_collective(parcel_count) — Synthetic dense-urban archetype (75 %
residential_primary · 15 % commercial_retail · 5 % commercial_office · 5 % institutional).
- collective.make_rural_collective(parcel_count) — Synthetic rural archetype (50 %
agricultural_active · 20 % agricultural_fallow · 20 % residential_primary · 10 %
conservation).
- calibration.py — Rate and weight calibration tools.
- guf_rate_calibration(inventory, target_guf_levy_ratio, population, epsilon) — Closed-form
linear solve to find the use-coefficient multiplier k such that aggregate GUF ≈
target × levy_revenue. Binary-verifies with a sample run; reports converged flag.
- guf_lvi_weight_sensitivity(inventory, epsilon, weight_variants) — Sweeps Location Value
Index weight configurations to quantify how sensitive aggregate GUF is to sub-index weighting
choices (centrality vs. transit vs. services vs. natural amenity). Ships five canonical
variants; callers may supply their own.
- land/__init__.py re-exports all four new public functions.
Multi-period automation→levy→GUF stress scenario
- scenarios/guf_stress.automation_levy_guf_stress(parcel_inventory, epsilon_start,
epsilon_end, n_periods, ...) — Period-by-period fiscal stress loop: as ε rises, levy revenue
(derived from the EOH pipeline) falls, GUF tracks the Ψ(ε) bell curve, and the sufficiency
guarantee cost evolves. Reports levy_peak_period, guf_peak_period, crossover_period
(first period where GUF exceeds levy), first_insolvency, compensation_adequacy, and
outcome ADEQUATE / PARTIAL / CRISIS.
Multi-period simulation scenarios (hours_eoh/scenarios/)
- long_run.py — canonical_arc_trajectory, trust_depletion_stress,
automation_transition_trajectory: three functions that call run_simulation() and return
multi-period trajectories with inflection-point detection and stressor profiles.
- indust_overshoot.py — indust_overshoot_baseline, indust_recovery_trajectory:
models the industrial-overshoot archetype (high capital age, degraded ecosystem, large
deferred-ecological backlog) and recovery pathways.
- shocks.py additions — labor_income_shock (income-fraction shock with solvency delta) and
compound_shock (combines ecological, demographic, and automation shocks; combined outcome
is always ≥ worst individual outcome).
Simulation engine extensions (hours_eoh/core/simulation.py)
- simulate_period(..., workforce_epsilon_decay: bool = False) — Optional parameter; when
True, workforce_fraction shrinks proportionally with rising ε. Default False preserves
backward compatibility.
- simulate_period(..., guf_net_inflow: float | None = None) — Optional GUF land-fee revenue
injected into the Trust each period.
- run_simulation() and the eoh simulate CLI forward both new parameters.
GUF calibration fix
- GUF_USE_* constants in data.py multiplied by 100 (e.g. residential_primary 0.10 →
10.0 TEH/SLU/yr, commercial_retail 0.30 → 30.0). At ε = 0.40 with a 1 M-population
territory (~420 k parcels), aggregate GUF is now co-equal with levy revenue — the design
target in the mission statement.
- guf_fiscal_integration() labor-income proxy replaced: was trust_balance × 0.5
(35× inflated); now uses eoh_to_teh_pipeline(epsilon, population)["teh_created"].
CLI (utils/)
- guf inventory calculate --parcels FILE [--epsilon ε] [--median-income TEH] — Batch GUF
from a JSON parcel file; prints aggregate summary table or JSON.
- guf inventory sweep --parcels FILE [--epsilon-start ε] [--epsilon-end ε] [--steps N] —
Sweeps aggregate GUF across the ε arc.
- guf inventory stress --parcels FILE [--epsilon-start ε] [--epsilon-end ε] [--periods N] —
Multi-period automation→GUF stress with per-period trajectory table.
- scenario command: 10 new scenarios wired — canonical-arc, trust-depletion,
automation-transition, indust-baseline, indust-recovery, labor-shock,
compound-shock, guf-integration, guf-writedown, guf-sweep.
- simulate command: --workforce-decay and --guf-inflow TEH flags.
Documentation and diagrams
- MkDocs GitHub Pages site deployed at https://hours-source.github.io/HOURS/.
- Five GUF Mermaid diagrams: calculation flow, LVI component weights, Ψ(ε) epsilon arc,
Trust fund flow, and ecological write-down pathways. Rendered SVGs in docs/images/.
Fixed¶
- eco-collapse-1 (closed) — Ecological collapse is now handled via the GUF layer
(
land/guf.py§9) rather than direct TEH destruction. Two pathways: restoration (V_s baselines reset to recovery target, revenue maintained) and abandonment (rebuilding surcharge R_b amortised over 50 years). Preventive monitoring viaeoh_accumulation_warning()(§9.8).research/writedown.pyre-exports with rationale. guf_net_inflowguard insimulate_period()corrected from> 0.0tois not Noneso negative inflows (subsidy-heavy periods) are no longer silently dropped.WORKFORCE_FRACTION_MINnamed constant added todata.py; replaces anonymous0.05literal in simulation.
Changed¶
- Test count: 1040 → 1169 (129 new tests across
tests/land/,tests/scenarios/).
0.1.0 — 2026-05-06¶
Initial public release of the HOURS EOH framework.
Added¶
Core package (hours_eoh/core/)
- trajectory.py — Canonical arc, ε derivation, canonical_physical_state(), compute_epsilon()
- eoh_generation.py — Four EOH domain functions: personal_eoh, infrastructure_eoh, ecological_eoh, knowledge_eoh, total_eoh
- registration.py — Per-domain sigmoid admission curves; personal_eoh_registration_share (near-zero at ε=0), total_registration_share (labor composite)
- eoh_fulfillment.py — EOH → TEH pipeline: human_eoh_share, human_eoh_per_domain, registered_eoh, eoh_to_teh_pipeline
- multipliers.py — Condition II multiplier band and tier logic
- fiscal.py — Fiscal architecture: levies, stewardship and ecological allocations (co-equal), sufficiency guarantee, trust management, care stipend
- prices.py — Price dynamics tied to human labor content: basket_price, purchasing_power, floor_purchasing_power
- capital.py — Asset and human capital lifecycle: make_asset, birth_event, maturation_update, death_event, writedown_trigger, execute_writedown
- eoh_dynamics.py — Time-evolution: eoh_compounding, asset_condition_trajectory, regenerative_offset, eoh_reduction_ratio
- population.py — Population structure, age distribution, demographic events (aging)
- workforce.py — Workforce lifecycle, domain headcount, competency reserve, apply_death_redistribution
- conditions.py — Structural Conditions I–IV enforcement: balance_check, condition_iii_balance_growth_check
- dashboard.py — Condition monitors and EOH/fiscal health indicators
- civilization.py — Endogenous ε from capital stock: civilization_epsilon, CAPITAL_MACHINE_PROFILES
- simulation.py — Period simulation engine: make_economy_state, simulate_period
Land module (hours_eoh/land/)
- guf.py — Ground Use Fee framework (NLSA TM-0042, 7th Ed.): 14 functions from epsilon_scaling through guf_trust_inflow
Scenarios (hours_eoh/scenarios/)
- sweep.py — epsilon_sweep: arc coherence check with fiscal solvency at every ε
- shocks.py — automation_failure_shock, demographic_shock, ecological_eoh_spike
- maintenance.py — deferred_maintenance_crisis, care_registration_delay
- recovery.py — maintenance_recovery_schedule, minimum_fulfillment_for_recovery
- sensitivity.py — fiscal_parameter_sweep, eoh_arc_sensitivity, epsilon_delta_sensitivity
Research (hours_eoh/research/)
- investment.py — rank_investment_candidates, optimal_investment, eoh_reduction_ratio (re-exported from core)
- writedown.py — Placeholder: ecological write-down for collapse scenarios (eco-collapse-1, future work)
Test suite - 1040 tests across 20 test files covering the full arc from ε = 0 to ε = 0.99 - Phase tests (1–14) cover the complete development arc - Module tests cover trajectory, civilization ε, GUF, and all scenario modules
Design invariants established¶
- ε is a derived observable, not a policy lever or generation-function input
- EOH generation takes physical state; EOH fulfillment takes ε
data.pyis the single source of truth for all named constants- Per-domain registration split: personal uses demand sigmoid; non-personal use labor composite
- Ecological and stewardship allocations are co-equal (neither is residual)
- Zero interest (Condition III): balances grow only through labor
- All functions verified at ε = 0 (subsistence) and ε = 0.99 (effective post-scarcity)
Known gaps¶
- eco-collapse-1 — Ecological write-down for collapse scenarios not yet implemented (placeholder in
research/writedown.py)