Skip to main content

householdplan

ci pypi python license checked with mypy ruff

Generate a written household financial plan: policies by domain, an action register, an assumptions table where every value carries a rationale and a revisit trigger, and the scaffolding to keep the plan current after it is written.

A household plan records what you do when something happens, so the decision gets made once, in advance, rather than under pressure. Most plans go stale because nothing forces the assumptions to be revisited and nothing records why a number was chosen. This tool generates both parts: the document, and the review structure around it.

Thirty-one policy rules across eleven domains, two dependencies, no language model, and no network access. The same inputs always produce the same document, because policy text comes from a YAML corpus rather than from generated prose.

Educational. Not legal, tax, or investment advice.

Install

pip install householdplan

Python 3.11+. Two dependencies (pydantic, pyyaml). No network access, no telemetry, no language model: policy text comes from a YAML corpus, so the same inputs always produce the same document.

Use

householdplan draft examples/couple.yaml -o plan.md   # the plan document
householdplan validate plan.md                        # structural checks
householdplan scaffold -o planrepo/                   # appendices + review template
householdplan export-rules -o rules.json              # the corpus, for other runtimes

Use as a library

Everything public is importable from the package root, so internal layout can change without breaking you:

from householdplan import PlanHousehold, PlanSpec, build_document, load_rules, render_markdown

spec = PlanSpec(
    household=PlanHousehold(couple=True, taxable=True),
    effective_date="2026-03-01",
    values={"savings-rate.rate": 20, "reserve-floor.months": 6},
)
document = build_document(spec, load_rules())
markdown = render_markdown(document)

load_rules() caches the parsed corpus, and the rules it returns are frozen, so calling it per request is cheap and no caller can rewrite policy text for another.

Storing a plan

PlanSpec() is valid with no arguments, which is right for a draft being filled in and wrong for a payload coming back from storage: a read that fails and returns an empty mapping would otherwise produce a complete-looking document instead of an error. Load stored specs through from_stored, which refuses anything untagged:

payload = spec.for_storage()  # stamps schema_version
restored = PlanSpec.from_stored(payload)

PlanSpec.from_stored({})  # ValueError: no schema_version
PlanSpec.from_stored(None)  # TypeError: not a mapping

This is a backstop rather than a substitute for a storage layer that raises on its own read failures.

What it generates

draft emits a seven-section document:

  1. Why we manage money this way
  2. Goals, in priority order
  3. Policies, grouped by domain
  4. Action register
  5. Assumptions
  6. Review and change policy
  7. Appendices to write next

scaffold emits the layer that keeps it alive: eleven numbered appendix skeletons (00 Summary through 10 References) with their table headers in place, a quarterly review template whose sections map one-to-one onto those appendices, and a review log.

Policy domains

Cash flow, liquidity, debt, investing, taxes, equity compensation, insurance, goals, retirement, estate and handoff, governance.

Each rule declares which households it applies to, so a solo household without equity compensation never sees rules written for a couple with vesting stock. A rule you switch off is recorded as a deliberate omission rather than dropped silently, which keeps a later review from relitigating a decision that was already made.

Rules are data

The corpus lives in YAML, one file per domain:

- id: reserve-floor
  domain: Liquidity
  label: Cash reserve floor and what happens if it breaks
  relevant: always
  default_on: true
  inputs:
    - {key: months, label: Reserve floor, kind: num, suffix: months of essential spending}
  assumption_keys: [months]
  variants:
    - when: always
      text: "{We} hold at least {n:months} months of essential spending in {t:accounts}.
             If reserves fall below that floor, optional taxable investing pauses until
             the floor is restored."

relevant and when are boolean expressions over six household flags (couple, dependents, both_retirement_plans, equity_comp, taxable, near_retirement) combined with and, or, not, and parentheses. A recursive-descent parser handles them, so a corpus file cannot execute anything and an unknown flag name fails at load.

Because the corpus is data rather than code, export-rules emits it as JSON for other runtimes to render, and a single edit to a policy sentence reaches every consumer.

Validation

validate runs ten structural checks: every enabled rule's inputs are bound, every assumption has a rationale and a revisit trigger, every action has an owner and a due date, goals are uniquely ranked, the disclaimer is present, no individualized securities advice, no overstated certainty, every number in the prose traces to a bound input, an effective date is set, and switched-off domains are recorded rather than dropped.

Scope

This generates a policy document from inputs you supply. It does not run projections, pick investments, or give individualized advice. Numbers you put in come back out with their rationale attached; it does no arithmetic of its own.

Related

The plan document pairs with projection tools rather than replacing them. A projection tells you whether the numbers work; this records what you will do when they stop working. planner-lab consumes this package as an optional extra and can build a plan straight from a typed case file, so the policy figures and the memo figures come from the same source.

License

MIT


#personal-finance #financial-planning #investment-policy-statement #household-budget #retirement-planning #financial-independence #document-generation #markdown #python #pydantic #deterministic #no-llm #open-source-finance #money-management #financial-literacy

Metadata

Release files for householdplan 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for householdplan 0.2.1
File Size Uploaded
householdplan-0.2.1.tar.gz 103.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for householdplan 0.2.1
File Interpreter ABI Platform
householdplan-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 150.9 kB

Release files / householdplan-0.2.1.tar.gz

Download URL householdplan-0.2.1.tar.gz
Size 103.3 kB
Tags Source
SHA-256 checksum
How to use checksums
ae89144b7568c956d5ff822dc5c5bbd82495ee6665c5efb3e81fcdfe3401f4a2
BLAKE2b-256 checksum
How to use checksums
56086ed16d1150d46cdf671ea7ce9cb9c3ea9fcb8de9a06e799b009322a4830d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.

Transparency log

Release files / householdplan-0.2.1-py3-none-any.whl

Download URL householdplan-0.2.1-py3-none-any.whl
Size 47.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ddf54c83f7e9a66b88d4ce6f8755d5cb089a84d9d263c9787371746ca6254f1d
BLAKE2b-256 checksum
How to use checksums
906ca1e439a4ad531295586b1bd7fa1e8b90844ccc56e73bafdc01c08eff380c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page