Architecture Note · 08

The amendment problem no attorney wants to solve for $400

BoardPath · May 2026 · Eric Tetzlaff

There is a document sitting in a filing cabinet — or more likely, a Google Drive folder with a name like "HOA Docs FINAL v3 USE THIS ONE" — that is wrong. Not wrong in a way anyone can easily see. Wrong in the specific way that legal documents accumulate wrongness over time: the original was correct when it was written, the first amendment was correct when it was recorded, and neither of them, read alone, tells you what the rule actually is today.

This is the amendment chain problem. It is endemic to HOA governance, and it has exactly one traditional solution: you hire an attorney to read every document in the chain, reconcile them manually, and produce what the industry calls an "Amended and Restated" version. That process costs between $500 and $1,500. It requires a member vote. It requires county recording. And it produces a document that starts going stale the moment the next amendment is recorded — which, depending on the association, could be next year.

BoardPath already had the amendment chain. Section-level parsing, authority hierarchy, the full corpus ingested and indexed. What it didn't have was a way to show you what all of those documents, read together and in order, currently say. The Consolidated Document View is that feature. And building it taught me something specific about where AI-assisted legal work stops and human judgment has to take over — a line I'm increasingly convinced most systems in this space are drawing in the wrong place.

The AI handles what requires intelligence. The architecture handles what requires guarantees. Conflating the two produces systems that are less reliable than either would be alone.

The first thing I had to solve wasn't the consolidation logic. It was the blindspot problem.

Governing documents reference their own amendments. A CC&Rs recorded in 1998 will say, in its amendment history section, that it has been amended by Amendment No. 1 dated March 2004, Amendment No. 2 dated November 2009, and so on. That's useful provenance — until you realize it also means an uploaded document might contain references to amendments that haven't been uploaded yet. A consolidation that ignores missing documents doesn't produce a current-state view. It produces a partially-applied view that looks authoritative and isn't.

I called these ghost amendments. A ghost is any amendment referenced by name or date in the corpus that hasn't been ingested — a hole in the chain that the system can see the shape of but not the contents.

Why regex was wrong

The detection approach mattered here. Regex felt like the obvious answer and was wrong. Amendment references in real governing documents are not consistent enough for pattern matching to catch reliably. "As amended by Amendment No. 3 (recorded June 2012)" is four different formats depending on the attorney and the county. GPT-4o-mini, scanning the first 14,000 characters of root document text, handles the variability without flinching. When ghosts are detected, consolidation refuses to proceed and surfaces exactly which documents are missing and where they appear.

Not a warning. A hard block.

The failure mode I was designing against: a board asks for a consolidated view, the system produces one, and the answer is wrong because three amendments weren't uploaded. The board acts on it. Three months later, a homeowner's attorney produces the missing amendments in a dispute. That's the scenario. The ghost block exists to make it impossible.

Once the ghost check passes, the mapping engine classifies every amendment section into one of four action types.

Replace
Full section swap. The parent text is archived; the amendment text becomes current. The original is accessible behind a toggle in the viewer.
Insert
A new section with no parent. Appended at the end of the consolidated document in effective-date order.
Delete
The section can't simply disappear — the consolidated view shows a bracketed placeholder, the removing amendment is named, and the original language remains accessible behind a toggle.
Partial
The most common real-world case. Stores inline_replacement_json — an array of {find, replace} pairs — in JSONB. The engine applies String.replaceAll() in sequence. The section structure is unchanged; specific words or phrases are different.

That last one is where it gets real. The most common real-world amendment isn't a full section replacement. It's a phrase change: "Replace '30 days' with '60 days' wherever it appears in Article VI." Treating partial amendments as first-class action types rather than collapsing them into replace is probably the most important correctness choice in the whole feature. A consolidation that replaces entire sections for word-level amendments produces a view that's technically correct and looks nothing like any document a human attorney would recognize. Boards work with these documents for years. Legibility matters.

The calibration decision

The amendment mapping engine uses GPT-4o in batches of five sections. The prompt returns action types and parent section IDs, and every returned ID is validated against actual database records before a mapping row is written. No hallucinated parent IDs reach the database.

I built a visible calibration gate into the codebase — a [PENDING] block in the amendment mapper file that the viewer also surfaces as a warning. The feature doesn't reach production association data until the mapping prompt has been validated against five to eight real amendment documents at ≥ 90% accuracy with zero hallucinated parent section IDs.

That gate is still pending. I'm writing this with it still pending. That's the point.

Conflicts happen when two amendments both target the same parent section. The chronologically later one governs — but the conflict itself is information. It means an association has amended the same provision twice, which is worth flagging even if the outcome is deterministic.

The consolidation engine detects conflicts before applying any amendments. Sections targeted by two or more amendments get conflict_flag: true. The amber left border and the "Conflict detected" chip appear regardless of which amendment resolved it. A user who sees that chip can investigate the chain. A user who never sees it can't.

A recurring design pattern

The information that something is complicated is itself valuable information, separate from the answer about what the complication resolved to. A system that surfaces only the outcome hides the history that explains it.

The output is labeled "CONSOLIDATED REFERENCE DOCUMENT — NOT A LEGAL INSTRUMENT" in every location where it appears: in the in-app viewer header, in the DOCX export running header and footer, on every page of the document, and in the version certificate that leads the export.

This isn't fine print. It's architecture.

"Amended and Restated" is a specific legal designation. It requires member vote, attorney drafting, and county recording. A BoardPath consolidated reference is not that — it is a current-state reading aid, not a legal replacement for the underlying documents. The distinction matters because people will use it in board meetings, in dispute conversations, in email threads. The label has to be prominent enough that no one accidentally treats the reference as the instrument.

The same disclaimer architecture exists elsewhere in the product — the Amendment Generator carries it — because the risk isn't that people misunderstand the feature in isolation. It's that a document that looks authoritative gets forwarded and cited without its label.

A consolidated view has a freshness problem that most cached outputs don't. The moment a new amendment is uploaded, the consolidated view is wrong.

The solution is living document invalidation. When a new amendment is ingested, the parse pipeline walks the amends_document_id chain to find the root document, then sets generation_status to stale on any ready consolidated views. The user sees an amber banner and a "Regenerate" button. The invalidation is non-fatal — errors are logged and swallowed rather than failing the ingestion — and it's one-directional. A stale banner doesn't prevent reading; it contextualizes it.

The governing principle

The system's job is not to prevent people from reading stale data, because sometimes stale data is the right data to read. Its job is to make the staleness visible. A board that sees an amber "this view was generated before the October amendment was uploaded" banner is equipped to make a judgment. A board that doesn't know the view is stale isn't.

Attorney consolidations cost $500 to $1,500, require a vote, and go stale. That's the market failure BoardPath is addressing with this feature — not a technological one.

The system has the amendment chain, the section-level text, and the authority hierarchy. The consolidation engine is pure deterministic logic after the mapping step. The AI component — GPT-4o for section mapping, GPT-4o-mini for ghost detection — handles the parts that require language understanding. The structural decisions — conflict detection, partial amendments, living document invalidation, the disclaimer architecture — are design, not inference.

That distinction is one I try to hold clearly: the AI handles what requires intelligence; the architecture handles what requires guarantees. Conflating the two produces systems that are less reliable than either would be alone.

The calibration gate is still pending. When it passes, this goes to production. Not before.

← Architecture Note 07 Next post →