Skip to content

About

AI-assisted IBC 2021 egress and occupancy plan review. A vision model reads the drawing; a deterministic engine applies the code and cites every finding.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Egress & Occupancy Plan Review Assistant

An AI-assisted plan-review tool for municipal building/codes reviewers. It reads a 2D architectural floor plan and produces a reviewer-ready compliance checklist against IBC 2021 egress and occupancy provisions — every finding carrying its reasoning and its code citation.

It assists a reviewer. It never approves or denies a plan.


Quick start

git clone https://github.com/Pothan0/floorplan_reviewer.git
cd floorplan_reviewer && npm install
npm run dev

Open http://localhost:3000. Click any sample drawing and the full review runs — no API key, no network, no configuration. That path is worth trying first.

Six samples ship with it. Four are ordinary submittals; two are deliberately deficient and worth opening first, because they fail for opposite reasons:

  • Taproom TI — a classification failure. The applicant calculated occupant load with the tables-and-chairs factor (15 sf net) and posted 120; the standing bar area is 5 sf net, which puts it at 520 and cascades into exit count, egress width, common path and remoteness. The building is sprinklered, but §1020.5 Exception 2 does not list Group A, so the 20 ft dead-end limit still governs.
  • Warehouse → Office conversion — a geometry failure. Loads and widths are all fine; what fails is a 200 ft deep floor plate with exits only at the ends and no sprinklers.

Requires Node 20.9+ (developed on Node 24).


Enabling image upload (optional)

The built-in samples and manual entry work offline. A Gemini key is needed for two things: uploading your own drawing, and the retrieval layer that attaches code sections to findings. Neither the checklist nor its verdicts depend on it.

cp .env.example .env.local

Put your key in .env.local:

GEMINI_API_KEY=your_key_here

Get one free from Google AI Studio. Restart the dev server afterwards. Without a key, uploading shows a friendly notice instead of failing — the compliance engine is unaffected.

The model defaults to gemini-3.6-flash; override with GEMINI_MODEL in .env.local.


Behind a corporate TLS-inspecting proxy

Skip this unless upload fails with unable to get local issuer certificate or a bare fetch failed.

Networks running TLS inspection (Zscaler, Netskope, Palo Alto…) re-sign HTTPS with a private root CA. Browsers trust it via the OS certificate store, but Node ships its own CA bundle and ignores the OS store, so server-side calls to Gemini fail.

npm run setup:ca

That exports the proxy's root CA to certs/corporate-root-ca.pem (Windows; the script prints the macOS/Linux equivalent). npm run dev then picks it up automatically.

This appends one trusted issuer — certificate verification stays fully on. Do not use NODE_TLS_REJECT_UNAUTHORIZED=0. The variable must be set before Node starts, which is why npm run dev goes through scripts/dev.mjs; setting it in .env.local will not work.


Scripts

Command What it does
npm run dev Dev server, with corporate-CA handling
npm run dev:plain Stock next dev, no CA handling
npm run build Production build
npm run setup:ca Export the corporate root CA (see above)
npm run export:samples Re-render the sample plans to PNGs in demo-plans/
npm run lint ESLint

How it works

Two kinds of work, deliberately kept apart: reading a drawing is perceptual and sometimes wrong; applying the code must be reproducible. So the model is confined to perception, and a trust boundary sits between it and everything else.

Stage What happens Who does it
Read Two parallel Gemini calls: one reads the overall dimensions and units, the other reads each room's box, name, use and any visible doors Model
Measure Scale is calibrated per axis, room sizes computed, printed dimensions reconciled against scaled ones Code
Confirm Extracted boxes are drawn back onto the original drawing; every value is editable Reviewer
Evaluate IBC rules applied; findings emitted with reasoning and citations Code

The model is never asked to do arithmetic, convert a unit, or decide compliance.

The retrieval layer

Compliance is calculated, not retrieved — each rule is a threshold applied to a measured value, and asking a language model to decide whether 245 ft exceeds 200 ft would throw away the one property that makes this reviewable. So retrieval is not in the decision path.

What it does instead is answer the question a reviewer asks after reading a finding: what else in the code bears on this? Every finding carries the sections that can modify it — §1017.2's nine cross-referenced conditions under a travel-distance failure, §1004.5's approval exception under an occupant-load discrepancy — set out in full, with the section number linking to the adopted text.

Two properties make that safe to print next to a verdict:

  • It cannot change a finding. The engine has already decided by the time retrieval runs. Context is added to the response, never fed back in.
  • It runs after, and independently. If /api/context fails or no key is configured, the checklist is unaffected.

Relations that are known are asserted rather than embedded, and retrieval supplements above a strict similarity floor. That is a measured decision, not a shortcut: the eligible corpus is a dozen chunks all describing egress in one code, so they sit close together in embedding space and cosine scores come out nearly uniform. Retrieval earns its place on the open question box (/api/ask), where the query is unconstrained and the full corpus is in play.

The corpus is generated from the rule tables in src/lib/ibc/data.ts — no ICC code text is reproduced in this repository.

Guardrails

  • Absent data is never a failure. No doors detected → needs review, never fail.
  • Doors are never invented. A fabricated opening makes an unsafe plan look compliant.
  • Estimates are asymmetric. A straight-line distance over a limit fails (the routed path can only be longer); under a limit it is needs review, never a pass.
  • No finding without a citation. The section reference is part of the result type.
  • Self-checking. Horizontal and vertical scales are cross-checked; a disagreement over 5% is reported instead of silently skewing every room.

Layout

src/
  app/
    page.tsx                 3-stage flow: intake → confirm → checklist
    api/extract/route.ts     Gemini vision → structured plan
    api/context/route.ts     Code sections attached to each finding
    api/ask/route.ts         Open questions, answered only from the corpus
  components/
    Intake.tsx               Upload, samples, manual entry
    PlanOverlay.tsx          Extracted boxes drawn on the original drawing
    PlanEditor.tsx           Confirm/correct the extraction
    Checklist.tsx            Findings grouped by category
    CheckCard.tsx            One finding + reasoning trace + code sections
    CodeLookup.tsx           Ask-the-code box
  lib/
    geometry.ts              Calibration, measurement, egress geometry
    planSvg.ts               Renders a plan as a life-safety sheet
    samples.ts               Six sample plans, two deliberately deficient
    rag/
      corpus.ts              Chunks generated from the rule tables
      store.ts               In-memory cosine store over the corpus
    ibc/
      data.ts                IBC 2021 rule tables + citations
      engine.ts              Deterministic compliance engine (no LLM)
      types.ts               Domain types
scripts/
  dev.mjs                    Dev launcher; sets NODE_EXTRA_CA_CERTS
  setup-ca.mjs               Exports the corporate root CA
  export-samples.mts         Renders sample plans to PNG
demo-plans/                  Sample drawings you can upload

src/lib/ibc/engine.ts is pure functions over a confirmed plan — no model, no network, no randomness. Same input, same findings, every time.


Code coverage

Encoded from IBC 2021 and verified section by section against ICC Digital Codes, which is also where every citation in the UI links:

  • Occupant load — §1004.2, Table 1004.5 (with gross/net basis)
  • Exit count — Table 1006.2.1, §1006.2.1.1 tiers
  • Egress capacity — §1005.3.2
  • Common path — Table 1006.2.1
  • Travel distance — Table 1017.2 (per occupancy group)
  • Exit remoteness — §1007.1.1 (½ / ⅓ diagonal)
  • Door size — §1010.1.1
  • Ceiling height — §1003.2 / §1208.2
  • Corridors — Table 1020.3 width, §1020.5 dead ends
  • IRC scope-out — Group R-3 dwellings routed to IRC R310/R311

Section numbering moved between the 2018 and 2021 editions in two of these — dead ends went from §1020.4 to §1020.5 and corridor width from §1020.2 to §1020.3 — and both were wrong here until they were checked against the published text.

Known limits

  • Irregular (L-shaped) footprints defeat single-dimension calibration. Flagged, not silently wrong — a real permit set produced an 11% scale disagreement and said so.
  • Room boxes trace the drawn extent rather than the inside face of walls, so scaled dimensions read ~1–3% large. A printed room dimension always wins when one exists.
  • Travel distance and common path are straight-line estimates, not routed paths.
  • Corridors and stairways must be entered by hand; they are not read from drawings.
  • Stairway egress capacity (§1005.3.1), accessibility (Ch. 11), fire-resistance (Ch. 7) and height/area (Ch. 5) are out of scope.
  • No persistence, export or permit-system integration — findings live for the session.

Adopting a state or local code

US jurisdictions adopt amended IBC editions rather than the base code, which is why state codes (Ohio's OBC, Florida's FBC) are IBC-derived. Every threshold lives in typed tables in src/lib/ibc/data.ts rather than being spread through the logic, so adopting one means overlaying an amendment set on those tables. The engine itself does not change.


Disclaimer

Demonstration prototype applying a curated subset of IBC 2021 Chapter 10 and Table 1004.5. Not affiliated with the ICC. It does not verify all applicable code, adopted local amendments, or accessibility provisions, and it does not constitute plan approval. Always defer to the adopted local code and a licensed plans examiner.

About

AI-assisted IBC 2021 egress and occupancy plan review. A vision model reads the drawing; a deterministic engine applies the code and cites every finding.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages