Skip to main content

Hiro Fukushima

Self-Correcting AI Platform

Verified Legal Content at Scale

Systems Architecture
Case Study
AISystems ArchitectureLaravelLegal TechMulti-Agent
The Gun Laws admin dashboard for massgunlaws.com, with one open event, 26 sources failing and the monitor run at 2:30 AM, source checks by kind of source over 30 days, sessions, search clicks, pages in Google's index and today's page views.

01. What problem it solves

Firearms law is one of the most complex areas of law in the United States, especially in Massachusetts. A gun owner answers to federal law, state law and local rules at the same time, and these layers contradict each other and keep changing.

Anyone who needs to know their state's firearms law finds no single source that is reliable, easy to follow and updated whenever the law changes.

Gun Laws is that source for the six states it covers, with a public website for each of them.

02. The work

I built the Content Engine to check content written by AI against its sources before it is published. To test it on content where every section number and date has to match the official text, I chose firearms law and built Gun Laws.

A reader who wants to apply for a License to Carry in Massachusetts finds the guide for it on massgunlaws.com. The guide tells the reader who it applies to and what to do, and it lists its sources with a link to each, on the Legislature's site and on mass.gov, so the reader can check the answer against the official text. From the guide, the reader reaches a list of every city and town in Massachusetts with the police department that takes the application in each.

The guide was run through the Content Engine. Its code confirmed the claims whose cited section of law had been found in the mirror, a local copy of the official texts, without asking a model. Its date check caught a claim that the model judging the claims then rated partially correct, and that claim was rewritten and released.

The guide how-to-apply-massachusetts-ltc in the Content Engine. Checked in code with no model, six citations were found in the mirror, MGL c.140 §131M, MGL c.140 §131F, Section 131, Chapter 135 of the Acts of 2024 twice and Guinane, each marked SPAN_FOUND, with the source file ma/mgl/c140/0131m-assault-weapon and its sha256 9cfe2b80c360. Caught by the date check, the sentence ending lawfully possessed on August 1, 2024) and location restrictions lost its last words, after checker:dates flagged a mismatch, the judge rated it PARTIALLY CORRECT and the decision was CHANGE, released as 99a0f76 on six sites.

03. My role

I am the sole designer and operator of Gun Laws. I designed the product and its design system, built the six state sites on one shared codebase with Claude Code and Codex, and check their content against the official law with the Content Engine.

04. Key decisions

The 42 sentences of the page mgl-c140-s129b-firearm-identification-card. A sample reads 3 of them. Every sentence reads all 42, with 29 backed, 11 no law and 2 corrected.
01

Every sentence is read against the official law

Earlier audits checked the pages through filters, such as the citations alone, samples of 30 claims per state or only the claims a first pass had flagged, and each of them called the pages accurate. A later pass still found wrong statements on pages that had passed, so I decided that every sentence of a page is read against the official law, starting with the pages people read most, because one complete read would have cost less than repeating those audits. A new article reaches a site's home page only after that read.

Refused by the source, mass.gov answered HTTP 403 with a block page and courtlistener.com answered HTTP 429 with a verification page, and removing a claim for the refusal is struck through and rejected. Held and read in a browser instead, the License to Carry guide had 13 holds, among them an EOPSS memo and a DCJIS page on mass.gov, both resolved in the browser.
02

A claim that cannot be verified does not count as correct

Mistakes about ballot measures survived two earlier checks, because claims the checks could not verify were counted as passed, and true claims about court cases were removed only because CourtListener and mass.gov refused the request. I decided that a claim that cannot be verified, when it carries a date, a number, a section or a deadline, is decided against the official text, and that a claim whose source could not be reached is held and read in a browser, never removed for that reason.

03

The law stays free, and professionals pay to reach its readers

Every article and guide stays free to read, and so does the email a reader gets when a saved article changes. The money comes from paid offers, such as a listing for firearms attorneys, and a listing goes live only after the attorney's bar number is checked against the state's public register.

04

Saved articles send an email at once, with a note written for readers

The approved design of the reader account also offered a daily or weekly digest of saved-article updates, and I removed it, because a reader should not miss an update of the law. A reader now gets one email as soon as a saved article changes, and only for changes that carry a note written for readers, so the internal note that every release writes never reaches the inbox.

The first library, a copy of the code kit, sorted its components by code export, with 100 in Catalyst, 36 in Domain, 5 in Layout and 13 in Chat, and the Catalyst Button was used 5 times, all on admin pages. The new library, the reference for new pages, sorts them by kind, with 66 icons, 62 buttons, 24 text fields, 27 selection controls, 18 overlays, 46 feedback components, 43 navigation components, 30 cards and 39 patterns, as one set of components with a brand mode per site, MA #1D4ED8, RI #B45309, CT #047857, NY #475569, IL #6D28D9 and CA #B20A7A.
05

The design system leads new pages, and the code follows

The first Figma library mirrored the code one to one, because the code was the source of truth for every value, and that made it a copy of the ready-made component kit in the code, with parts the public sites never use. I rebuilt it from the ground up as a new library that is the reference for new pages, with one set of components that switches between the brand colors of the six sites, and the code follows when a page is built from it. Every value in it still traces to the code or is marked as not in code yet.

05. How it works

Six sites run on one codebase

The six state sites run on one shared codebase and differ only in their configuration, so a fix to the code reaches every state with one release. Every command declares which states it runs on, and every change to content is locked to its own state, so a fix for Massachusetts cannot touch a California page that has the same address. A finding that also concerns another state goes into a shared register, and that state does not count as done until the finding is handled there.

One codebase, where config/state.php reads the state code, the domain and the brand from the environment, every command declares its states with #[RunsOn(['MA'])], every content change is locked to its state, and a finding open in a state in CROSS-STATE-FINDINGS.json keeps it from done. It serves six sites, massgunlaws.com, ilgunlaws.com, rigunlaws.com, caligunlaws.com, connecticutgunlaws.com and nygunlaws.com, each with its own STATE_CODE.

The sources are watched on a schedule

Monitors run every day and check each source on its own schedule. They watch the legislatures' sites and the agency pages, new firearms opinions in the courts each site follows and the dockets of the cases the pages cite, both through CourtListener, new firearms bills through LegiScan, and for Massachusetts the roster of approved guns and the licensing pages of the cities and towns, from which the list of where to apply is kept. A change on a source becomes a change event, and noise such as a reordered docket is filtered out in code. Twice a day a scheduled review by an AI agent works through the open events and rewrites the passage of a page that a change affects.

Monitor events. A changed index timestamp on a CourtListener search, reordered entries on a court docket and an outage counter on a town licensing page, ongoing for 3 hours, are filtered in code. The handgun edition 2026-10 on the Approved Firearms Rosters opens MA 306.

The mirror is refreshed from the official files

The state laws in the mirror are refreshed every day from the legislatures' own files, one file per section of law, so a section whose text changed shows up as a difference against the copy before. Court opinions and agency documents are added to the mirror when a page needs them. The roster of approved guns in Massachusetts comes from the mirror alone, and a new edition is accepted only when every line of the official PDF's roster is matched, with none left unmatched.

The mirror holds _STATE-LAW at release 2026-10-24-v1.29, with a folder per state such as ma/ with its statutes, regulations, bills, cases and the handgun roster of October 2026 added in v1.29, and _FEDERAL-LAW with the U.S. Code and eCFR. Its history shows v1.29 for the Massachusetts handgun roster, October edition, and v1.28 and v1.27 for the New York and California reliability rounds. Next to it, monitor event MA 306 on the Approved Firearms Rosters of EOPSS on mass.gov, checked 2026-10-24 at 07:30Z. The fingerprint changed since the last check, the edition went from 2026-08 to 2026-10, two pages still name the August edition and massgunlaws.com is not current. After review, two pages were rewritten, release ffb259b went out and the gate passes.

Every text that states the law is reviewed

The claims of every article are recorded in a ledger, and every other text that states the law, such as the FAQ, the glossary, the search descriptions and the cards for ballot measures, is recorded with a fingerprint of its reviewed wording. When such a text changes, or new legal wording appears in the page code, the check fails until the text has been read against the official law. The gate exists because a check of the FAQ found answers that had drifted from the law while every check on the articles passed.

A text outside the articles in the ledger, the legal_texts entry for state MA with the text key article:18-usc-921-931-gun-control-act-overview#seo_description, its text_sha256 f2d4d031, the verdict CONFIRMED and the review reference 2026-10-17 legal text outside articles. The FAQ, the glossary, the search descriptions and the ballot measure cards are recorded the same way. When the wording changes, the new sha256 no longer matches f2d4d031 and legal_text_outside_ledger fails until the text is read against the official law, and then CONFIRMED lets the gate pass.

A change ships only through the release

Every edit to an article ships as a database migration that applies only where the old text still stands exactly as expected. The release checks the wording, checks that every section of law the new text cites is in the mirror, and for Massachusetts also on the Legislature's site, applies the migration once in a test run that is rolled back, and then deploys it to all six sites. After the release the new text is confirmed on the live page. A state counts as current only when every page is covered by the ledger, no change event of a required source is open, and every required source was checked successfully on schedule.

The currency gate of the six sites after the monitor run of 2026-10-24. massgunlaws.com is blocked by one open event, MA 306, while ilgunlaws.com, rigunlaws.com, caligunlaws.com, connecticutgunlaws.com and nygunlaws.com pass with none open. Seven gate checks for massgunlaws.com pass, from scan complete to deployment verified, and the check for no open change on a required source is held by MA 306. One open event holds a site until the review resolves it. The other five pass while it waits.

One ruling, from the monitor to the page

When the Massachusetts Appeals Court ruled that a conviction for carrying a loaded firearm requires knowing it was loaded, the monitor recorded the new opinion as a change event. The opinion was read and added to the mirror, and the passage of the vehicle carry page on that offence was rewritten from the statute and the ruling, with two new sources. The edit passed the checks and the test run, went out to all six sites with one release, and the new text was confirmed on the live page.

Commonwealth v. Jackson, Appeals Court No. 25-P-933, traced through the system. The change event MA 238 came from the Appeals Court list, the mirror added ma/cases/commonwealth-v-jackson-2026.md, the vehicle carry page had its passage rewritten with MGL c.269 §10H and Commonwealth v. Jackson as new sources, the write-time check and the rehearsal passed, release 3870995 went to six sites, and the live page confirmed the new text with deployment_verified.

06. Evidence

581pages read sentence by sentence
24,733sentences read against the official law
2,248texts outside the articles reviewed
351towns checked word for word
Every page of the full read as one bar, grouped by site and sorted by length, each bar as tall as the page has sentences, on massgunlaws.com with 110 pages, ilgunlaws.com with 98, rigunlaws.com with 76, caligunlaws.com with 124, connecticutgunlaws.com with 70 and nygunlaws.com with 103. 581 pages across six sites, each read sentence by sentence against the official text.

24,733 sentences read against the official law

The full read, in which every sentence of a page is read against the official law, went through 581 pages of the six sites, 24,733 sentences. A page counts as done when every sentence has a final verdict, its fixes are live and the checks pass. Before a page was released, each quote was checked against its source file and each verdict was read next to its quote.

2,248 texts outside the articles reviewed

The check of the text outside the articles, from the glossary to the search titles and descriptions, covered 2,248 texts, and each of the 1,467 that states a legal claim was read against the official law. The answers to frequently asked questions were reviewed against the official law in their own check.

The roster matched the official editions

After the import from the mirror, whose editions were matched line by line to the official PDFs, the roster page listed the mirror's 1,542 approved gun models.

351 towns checked word for word

The list of where to apply covers all 351 cities and towns of Massachusetts, and every address, phone number and quoted local rule in it was checked word for word against a page or document saved from the town's or the police department's own site.

30 random claims per state checked outside the system

In each state, thirty claims drawn at random were read against official text fetched again for the check, without the engine and without the mirror, and after the follow-up the six sites agreed with the official text on every one of them.

All six states current

All six states count as current, with every page covered by the ledger, no change event of a required source open, and every required source checked on schedule.

30 random claims per state, checked outside the system. On massgunlaws.com, ilgunlaws.com, rigunlaws.com, caligunlaws.com, connecticutgunlaws.com and nygunlaws.com, all 30 agree with the official text.

07. What I learned

The record of the work shows how to improve it

Every page of the full read keeps a record of what reading it cost and what the review settled, down to the time and tokens the reading model used for each part of the page. After the first 70 pages I had those records analysed. They showed that each page was read in pieces of up to 25 sentences, and that every piece paid the same price to start before its first sentence was read. I approved all nine recommendations of the analysis, the reading became a skill of its own, and a page of up to 60 sentences is now read in one piece. In the pilot on five Illinois pages, that halved the reading model's tokens per page against comparable pages. For anyone running AI on repeated work, a record of every run shows where the next one can cost less.

A page record before and after. Before, in pieces of up to 25 sentences, the guide how-to-apply-massachusetts-ltc with 58 sentences was read in five pieces, 20, 21, 22, 29 and 30, taking 24.9 minutes and 631,896 tokens for the page. After, in one piece of up to 60 sentences, il-non-resident-concealed-carry with 43 sentences took one piece, 5.7 minutes and 145,183 tokens, where before every piece paid about 77,400 tokens to start, before its first sentence. The reading model's tokens per page fell from 350,759 on 33 comparable pages to 169,372 on five Illinois pilot pages.

Each round starts from what the last one learned

I decided that each state is brought up to date in a round of its own, and that every round ends by writing its lessons into the skill that runs the rounds before the next state starts. The skill carries the lessons of Connecticut, Illinois, the sweep that cleared the open items of the first four states, California and New York, each a rule a round worked out, such as testing whether a site that seems to refuse a request has a fault in its certificate before calling it blocked. That sweep wrote that the independent check of thirty random claims against freshly fetched official text runs in every state, and the California and New York rounds that followed both ran it. For anyone running the same work again and again, writing what each run taught into the instructions the next run starts from means no run has to learn it twice.

A lesson in the round skill, gl-reliability, Lessons from Illinois. What looks like a block can be a TLS fault. ilga.gov omitted its intermediate certificate, stalled on curl's default key share and refused the curl user agent. Test with --curves, --cacert and a user agent before calling a host blocked, and add the host to config/source_hosts.php. The lessons the skill carries, Connecticut written, Illinois this lesson, the sweep with the independent check in every state, and California and New York, which both ran the independent check.