AI/legal-use disclosure: This repository is experimental, AI-assisted workflow software. It is not legal advice, not a primary legal source, and not lawyer-reviewed as a complete statement of law. Outputs are first drafts for human review, intended to reduce creation effort while increasing focused review effort. See AI_DISCLOSURE.md.
This repository is licensed Apache-2.0, but installing it pulls in AGPL-3.0 code.
PyMuPDF (imported as fitz) is dual-licensed AGPL-3.0-or-commercial by Artifex.
It is a required dependency of this snapshot (requirements.txt), and the engine layer also reaches it through maine-forms-engine.
If you convey a work combining this code with PyMuPDF, or expose it to users over a network (AGPL-3.0 §13), the AGPL-3.0 terms attach to the combination. Artifex sells a commercial license if that is not acceptable for your deployment.
This repository is archived and read-only — a snapshot frozen in July 2026, not maintained. This notice was added later to disclose a dependency term the Apache-2.0 LICENSE alone does not mention. It does not change the license of this repository's own source, which remains Apache-2.0.
Fill the tax forms that ride along with a business formation, a real-estate closing, or an estate — Maine Revenue Services forms and federal IRS forms, one self-contained folder per form, filled deterministically from structured case data.
This is a sibling of maine-corporation-forms,
maine-court-forms, and
maine-probate-forms: same
form-by-form layout, same fetch-on-demand + drift-detection model, same
deterministic fill engine. The blank PDFs are fetched on demand from the
official source and never redistributed (see Getting the blanks).
⚠️ Not legal or tax advice — for professional use only. This is software that produces draft forms. It is meant to be used solely as one component of a broader workflow that is implemented, supervised, and reviewed by a licensed attorney or qualified tax professional — not as a do-it-yourself substitute for professional advice. Output is a draft that may be wrong; verify every form against the current official source and applicable law before filing. See DISCLAIMER.
| Domain | Forms |
|---|---|
| Corporations | IRS SS-4 (EIN), IRS 2553 (S-corp election), IRS 8832 (entity classification), MRS 1120ME (corporate income), MRS 941ME / 900ME (withholding), MRS W-4ME |
| Real estate | ME RETTD (real estate transfer tax declaration) |
| Probate / estates | IRS 706 (federal estate tax), IRS 1041 (estates & trusts income), IRS 56 (fiduciary notice), MRS 706ME (Maine estate tax), MRS 700-SOV (statement of value), MRS 1041ME (fiduciary income) |
SS-4 and 706 are cross-listed (an estate also needs an EIN). See
catalog/by_domain.json.
14 forms — every form now fills. Seven Maine Revenue forms were mapped in
maine-court-forms and lifted here; the rest were mapped in this repo.
- Mapped & verified (5): MRS 706ME, 1120ME, 941ME, 900ME, W-4ME —
widget-survival confirmed against the current maine.gov blanks. The 706ME
residency and marital-status groups and the W-4ME filing-status group are
declared
"fill": "manual"radio groups (same yellow-light treatment as below). - Mapped, machine-verified (2): MRS 1041ME (the current maine.gov blank
had drifted from the mapped revision; rebuilt deterministically against the
current widget tree — 123/125 widgets, with a
field_splits.jsondetaching its shared area-code field) and MRS 700-SOV (was an empty recipe pointer; direct-mapped from its descriptive widget names — 42/44 widgets). Both fill end-to-end with every sample value confirmed on reopen (every fillable mapping now recordsbuilt_against_sha256— see Staying current). Their radio groups (1041ME third-party designee Yes/No, 700-SOV Resident/Nonresident) are declared"fill": "manual"inmapping.json: the engine never writes radio groups, and the fill report carries a yellow-lightradio_groupsentry with the option suggested from the case — select it by hand. Not yet human-verified field-by-field. - Opus-adjudicated (7): IRS SS-4 (44 fields), 2553 (23), 8832 (53), 706
(146), 1041 (79), 56 (33), ME RETTD (74). Drafted from the rendered form by the
Qwen-VL cluster (
tools/vision_map.py), then reviewed field-by-field against each printed caption by Opus (tools/opus_adjudicate.py), which corrected 86 keys and removed 15 non-data widgets — most notably realigning IRS-1041's shifted income/deduction lines (68 fixes) and IRS-SS-4's over-split city/state/zip block (9). Each form records its corrections undermapping.json.adjudication. The big returns map identity/party fields; some numbered line items remainfacts.*. ME-RETTD + IRS-SS-4 fill end-to-end.
Two canonical models, for now. The five inherited Maine Revenue forms use the court library's
parties.<role>model; the vision-mapped forms above use the tax-native roles (entity,responsible_party,decedent,executor,fiduciary,transferor/transferee,property). Unifying the two is a roadmap item; until then, read each form'smapping.jsonfor its keys — both shapes are documented indocs/integrations/README.md.
Six forms (MRS 1041ME, 1120ME, 706ME, W-4ME; IRS 1041, 706) carry a
computations.json next to mapping.json declaring the arithmetic the form
itself prints ("Total payments. (Add lines 7a, 7b and 7c.)" — every
formula_text is quoted verbatim from the blank; no statutory rates or tax
tables are encoded from memory). The shared engine evaluates it
topologically: omit a computed key (with its inputs supplied) and it is
computed and filled, reported under computed_fields; supply it and your
value is written as-is — a contradiction only adds a
COMPUTATION_MISMATCH entry under computation_warnings (CLI and MCP
fill_form alike). Warnings only, never blocking, and nothing is embedded in
the PDF — no AcroForm calculation JavaScript. Lines whose printed math is
conditional (e.g. 706ME amount-due vs refund-due, 1120ME tax-due vs
overpayment) or split across dollars/cents widgets (941ME) are deliberately
not declared.
Blank forms are not redistributed here. Maine forms are public records of
Maine Revenue Services; federal forms are public-domain U.S. Government works.
Fetch on demand; each download is verified byte-for-byte against
catalog/pdf_manifest.json:
python3 tools/fetch_pdfs.py # all forms
python3 tools/fetch_pdfs.py --forms MRS-706ME # a subsetEvery mapping is built against one specific revision of the blank, pinned by SHA-256 in the manifest. Agencies re-issue forms yearly; when the bytes change, field layouts can move and a fill built on the old mapping lands values in the wrong place. Two guards:
python3 tools/check_upstream.py # re-probe official URLs; flag CHANGED / GONEcheck_upstream re-downloads each blank, hashes it, and reports drift; it is
read-only and exits non-zero on any change, so it runs as a weekly early-warning
(.github/workflows/drift.yml). At fill time the engine checks the on-disk
blank against the manifest — TTF_VERIFY_BLANK=warn (default), strict, or
off (MCF_VERIFY_BLANK is honored as a fallback) — so a re-issued blank
can't be filled unnoticed.
Every fillable mapping.json also records built_against_sha256 — the
manifest revision its widget references were last verified against
(tools/verify_mapping_fields.py, which re-checks every mapped field against
the pinned blank's AcroForm tree before stamping). The engine refuses to fill
when the manifest moves off that revision; a mapping that fails verification
stays unstamped and goes remap-pending instead.
Draft (vision-mapped) tier. A vision-mapped mapping is an unreviewed
vision-LLM draft ("review before production") that has not yet been through
opus-adjudicated/verified. Because these maps back real IRS/MRS PDFs, the
engine refuses vision-mapped by default — it is not in the reviewed
FILLABLE_STATUSES. Filling a draft is an explicit opt-in, which warns loudly
and must be human-reviewed before any real filing:
python3 -m engine.fill_via_mapping --form IRS-SS-4 --allow-draft ...
# or: TTF_ALLOW_DRAFT=1 python3 -m engine.fill_via_mapping --form IRS-SS-4 ...
# or, in code: fill_via_mapping(form_id, facts, out_dir, allow_draft=True)pip install -r requirements.txt # PyMuPDF
python3 tools/fetch_pdfs.py --forms MRS-706ME # download the blank, verified
python3 -m engine.fill_via_mapping --form MRS-706ME --case forms/MRS-706ME/examples/sample_case.json --out out/706me.pdfThe engine resolves each form's mapping.json against a canonical fact object
and writes the filled AcroForm. Unmapped forms (status unmapped) carry a
widgets.json inventory but no mapping.json yet.
forms/<FORM_ID>/
form.yaml metadata: title, agency, domain, page/widget counts, status
widgets.json raw AcroForm widget inventory (name, type, page, rect) — mapping input
mapping.json canonical fact-key -> widget (mapped forms)
schema.json JSON Schema for the fill data (mapped forms)
fields.csv reviewable field inventory (mapped forms)
SKILL.md / README per-form guide (mapped forms)
examples/ sample_case.json — fictional fact pattern covering the mapping
catalog/
source_urls.json form_id -> official URL + domain grouping
pdf_manifest.json per-form sha256 + bytes + pages for fetching/verifying blanks
forms_index.json master list (generated)
by_domain.json forms grouped by transaction domain (generated)
engine/ deterministic AcroForm fill engine (PyMuPDF) — thin shims over
fill_via_mapping.py form_filler.py field_split.py text_fit.py verify.py
the shared `maine-forms-engine` package (required; see
requirements.txt), configured with this repo's policy:
status allowlist, built_against_sha256 staleness gate,
diagnostics result dict
tools/
fetch_pdfs.py download verified blanks
build_manifest.py fetch + hash + dump widget inventory
check_upstream.py re-probe official URLs; flag revised forms
verify_mapping_fields.py re-verify mapped fields vs the pinned blank; stamp built_against_sha256
vision_map.py Qwen-VL draft mapping from the rendered form
opus_adjudicate.py Opus caption-grounded review of the drafts
infer_labels.py heuristic widget-caption inventory
gen_catalog.py regenerate the catalogs
gen_skill.py regenerate per-form SKILL.md + sample case (mapped forms)
agent_server.py MCP server (find_forms / get_form / fill_form)
docs/integrations/ the canonical fact object (case shape) reference
.mcp.json MCP registration; AGENTS.md / CLAUDE.md — agent guide