Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Groundwork review engine

A small, deterministic document-review engine for affordable-housing compliance files (LIHTC tenant recertification packets), with a second document domain (insurance certificates) built on the same core. It reads a structured packet, re-checks the facts against the source documents, and returns severity-classified findings that each cite where they came from. It never states a regulatory conclusion: that decision belongs to the human certifier, and the engine refuses to produce a report if any finding tries to make it.

Status: v0, a working proof built on fictional data only. It has never processed a real packet, has no users, and is not a product. It exists because I spent a summer doing this review by hand and wanted the checking to be reproducible instead of dependent on my attention.

Why it exists

In June 2026 I ran an annual housing-department recertification cycle for the regulated units of a Los Angeles multifamily property: mapping every source document to the agency's 15-item checklist, staging tenant packets for the certifier, and checking automated output against the source documents. That checking turned up errors that the automated audits had passed.

The lesson was specific: the failure points sit at the seam between extraction and the person who has to act on it, and they are only visible to someone who knows the workflow. This engine is an attempt to encode that seam as checks.

What it does

Given a packet (household, Tenant Income Certification, supporting documents, and the property's rule table), it runs six single-purpose checks and renders a findings report:

Check Catches Severity it can raise
completeness a required document type is missing Material issue
income-consistency TIC income ≠ income the pay stubs substantiate (recomputed, de-duplicated) Material issue
ami-eligibility substantiated income vs. the property limit, as an observation Observation / Clarification
signatures the TIC is unsigned Critical blocker
dates an income or asset document is outside the freshness window Administrative defect
duplicates the same document counted twice Administrative defect

Every finding carries a SourceRef back to the field or document it came from. The report is a draft for the certifier, not a determination: see samples/lihtc-sample-report.md.

The same core was then reused for a second domain — certificate-of-insurance review — with six more checks (src/coi/). That reuse is the one architectural claim the repo makes.

What it deliberately does not do

  • It does not decide eligibility. src/boundary.ts scans every finding for conclusion language ("ineligible", "approve", "deny", …) and the engine throws before rendering. There is a test for it, so the guarantee is checked on every run of the suite.
  • It does not use a model. Every finding comes from exact math, checklist matching and date logic. Extraction from scanned PDFs (where a model would belong) is out of scope for v0.
  • It does not touch real data. Every fixture is labelled fictional and the names are made up.

Run it (Node 24+, zero runtime dependencies, no build step)

node src/run.ts                          # review the hardest fictional LIHTC packet
node src/run.ts fixtures/packet-clean.json
node src/coi/run.ts                      # the insurance-certificate domain
node test/engine.test.ts                 # 20 tests
node test/coi.test.ts                    # 13 tests

A defect worth reading about

My own review found a bug the tests had missed: two checks each summed pay stubs independently, so a duplicated stub double-counted income (from $26k to $52k). The fix consolidated income substantiation behind one de-duplicating function (src/income.ts) that both checks depend on, so their numbers cannot disagree, and the tests now assert on the computed value rather than on the presence of a finding. The decision log is in DECISIONS.md.

What I did, and what I did not

I did the manual work this automates, wrote the rules (what a defect is, where the boundary sits, what must be traceable), directed the build, found the defect above, and I run and read the tests. The code was written with heavy AI assistance under that direction. I would not describe myself as a software engineer; I would describe this as a domain user encoding the checks he wished he had.

Layout

src/engine.ts      orchestration: checks → boundary → rollup → render
src/checks/        one file per check, registered in CHECKS[]
src/boundary.ts    the conclusion-language scanner (runtime guarantee, covered by a test)
src/income.ts      single source of truth for substantiated income
src/finance.ts     exact money math, tested separately
src/coi/           the second domain on the shared core
fixtures/          fictional packets and sample rule tables
samples/           rendered reports from the fixtures
test/              33 tests across both domains

MIT licensed. Fictional data only; please do not run it on real resident files.

About

Deterministic document-review engine for LIHTC recertification packets and insurance certificates. TypeScript on Node 24, zero dependencies, 33 tests, fictional data only.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages