00 · Executive Brief

The zoning tool: what works, what's stuck, what we decide.

The parcel backend works. The zoning intelligence is typed in by hand, district by district. That is the wall. This brief is the case for turning rules into reviewed data and computing one authoritative answer on the server.

Built from a full code review + the live API + the Aug 10 & Aug 17 tactical calls · Rowan · 2026-08-18

Today · Verified

The parcel backend works

Address in, parcel found, zoning district read: fast, versioned, already useful. Keep it.

Bottleneck · Verified

~25–30

approximate manual actions to add one zoning district. Uses and formulas are hand-authored; matching is exact-string; the math runs in the browser.

Proposed fix

Rules become reviewed data

AI drafts from published ordinances → a human approves → approved rules sync to the fast store → one server verdict layer computes the answer.

Outcome

One backend, four surfaces

Homeowner ADU tool · realtor utility · chatbot flow · per-listing zoning cards. "Address in" becomes a plain-English answer.

Decision strip · Decision Required

Nothing below is approved yet

Wed, August 19, 2026 · Scott

Rules-store architecture, the canonical column set, and sync/cache performance.

To validate

Thu, August 20, 2026 · Steve / Barry

Priority user, approved direction, budget/timeline and developer sourcing.

Decision required

Before any branded launch

Authentication, access control and real market coverage. See 08 · Launch Gates.

Launch blocker

State of the three layers

Parcel layer

Built and working. Solid fill: verified today.

Rules layer

Exists, but hand-typed. Hatched fill: human labour per district.

Verdict layer

Empty outline: no server-side evaluator exists yet.

2 launch blockers open in 08
8 gates tracked, none closed
7 decisions on the table in 09
Verified today / keep Manual today Risk / launch blocker Structured data / rebuilt AI-assisted (drafting only) Product / system

Every status is stated in words as well as colour.

01 · Address → Answer

What the tool does, in seven steps.

One pass through the whole experience before any architecture. Each step is labelled by how it works today.

Journey board · address to answer

Seven steps · read left to right, then down

01

Address

A visitor types a property address.

Visitor

02

Parcel

Matched in county parcel data, versioned by upload.

Automatic

03

District

The zoning code on the record, for example RM8.

Automatic

04

Rules

What the district permits, read from a hand-filled grid.

A person types this

05

Calculation

A per-district formula, run in the visitor's browser.

Hand-built · in browser

06

Verdict

A plain-English answer instead of a grid of numbers.

Proposed · not built

07

Matching cottage

The Compact Cottages model that fits the allowed size.

Proposed · not built

Where it ends today

Step 05. The visitor reads the numbers and works out the meaning themselves.

Note on steps 04 and 05

The hand-authored spine: the use grid, the per-district formulas, and the exact-string match between a parcel and its rules.

Note on steps 06 and 07

Dashed cards are proposed, not built. Nothing customer-facing turns the numbers into an answer yet.

02 · Today vs Target

Stage by stage, exactly what changes.

Seven stages, each one column. The two cards in a column are the same stage before and after.

Swap board · one column per stage

Upper card: today · lower card: proposed

01

Address

Typed by a visitor

same ↓

Address

Unchanged

02

Parcel lookup

Fast, versioned, working

kept ↓

Parcel lookup

Same backend

03

Exact-string match

Drift shows nothing

fixed ↓

Normalized key

Safe state on unknown

04

Use grid by hand

One keystroke per cell

becomes data ↓

Approved rules

Drafted, then approved

05

Formula by hand

Numbers baked in

becomes data ↓

Same rules record

Parameters, not code

06

Browser math

Plus a second evaluator

moves to server ↓

Verdict engine

One evaluator

07

Grid of numbers

Reader does the work

becomes an answer ↓

Verdict and model

In plain English

Columns 04 and 05

Two hand-authored stages collapse into one approved record.

Column 06

The only stage that changes machines: off the visitor's browser, onto the server.

Columns 01 and 02

Untouched. The rebuild is the right half of the board.

The one-sentence difference

The hand-authored spine becomes reviewed data, and the browser math becomes one authoritative server verdict.

Adding a market becomes a review rather than a rebuild. Quantified in 05 · Why it doesn't scale.

03 · Worked Property Example

Same RM8 rules. Different parcel. Different verdict.

Two real Asheville properties in the same zoning district. The rulebook does not change; the parcel inputs do.

Input A · the parcel

{{ pName }}

{{ pKind }}

Parcel record

{{ pParcel }}

Zoning district read

{{ pDistrict }}

Lot schematic · not to scale

Existing home · ~760 sq ft
ADU up to ~530 sq ft
No primary home yet
ADU max 0 sq ft

Outer line: the lot. Dashed line: the buildable area inside the front, side and rear setbacks.

Automatic · verified today

Input B · shared rulebook

RM8 rules object

Identical for both properties.

Permitted use

{{ pUses }}

Dimensional standards

Front / side / rear 15 / 6 / 15 ft. ADU capped at 70% of heated living area, maximum 800 sq ft.

Hand-authored today

Output · the verdict

Calculation

{{ pCalc }}

{{ pVerdict }}

{{ pModel }}

{{ pLesson }}

Preliminary estimate · not a permit determination

Formula and supporting detail

floor( min(0.70 × heated_living_area, 800) / 10 ) × 10

Fairfax: approximately 760 sq ft of heated living area on a 0.26-acre lot returns approximately 530 sq ft. Old Haywood: no primary home, so the ADU maximum is 0 and the story becomes building a primary home first. Full worked numbers and sources are in the appendix.

04 · Verified Current System

A system health check, not a wish list.

Every statement in the first two columns was checked against the existing code and the live API. A working three-tier app on Compact Cottages' DigitalOcean: NestJS and Postgres.

Keep / reuse

The parcel half is solid

zones-api: NestJS and Postgres. Parcels loaded from CSV, versioned and activated; scales to 100k–1M records.

Verified today

Fast public search by address or PIN (trigram index).

Verified today

The matrix-and-formula concept itself is sound. It needs to stop being hand-typed.

Recommended reading of the evidence

Rebuild / replace

The zoning-intelligence layer

The permitted-use grid is one global sheet, filled one keystroke per cell. The bulk-import button is dead code.

Verified today

Size formulas are hand-built per district with every number baked in.

Verified today

The answer is computed in the browser, and the admin preview uses a second evaluator: two computation paths.

Verified today · drift risk

Parcel-to-rule matching is exact-string; drift shows nothing rather than an error.

Verified today

Launch blocker

Security and access control

Does not block the rebuild. Must be closed before a branded or public deployment.

The read API is public and unauthenticated.

Verified today · must fix before launch

The admin password resets to a default value on every boot, and a hard-coded fallback secret is present.

Verified today · must fix before launch

No role checks: any logged-in viewer can rewrite the rulebook.

Verified today · must fix before launch

05 · Why It Doesn't Scale

Two multipliers, one naming problem.

Scott, the internal zoning specialist, maintains the translator by hand today. The original developers required manual rule entry per jurisdiction on every data upload, which is exactly why the dimensional standards are hard to maintain.

Approximate operational illustration · not production telemetry

~25–30

manual actions per zoning district: approximately 15 permitted-use cells plus 8–10 formulas

×

~15–30

zoning districts in a typical county

×

many

counties, if coverage is going to mean anything to a realtor

Thousands to tens of thousands of manual rule entries, re-verified on every data refresh.

One county today · every cell a keystroke

Every cell in that grid stands for a value a person types and then retypes after a data refresh. Schematic, not a count.

vs

Same county as proposed · one reviewed record set

1 review, then approve Drafted rows, checked against the ordinance

Effort per new market stays roughly flat, because the work becomes reading rather than typing.

The standardization wrinkle · raised Aug 17 · the developer must design around this

Rows vary by jurisdiction. Columns standardize.

Asheville rows

RS2 RS4 RM8 RM16

Buncombe County rows

R1 R2 R3 OU

Shared canonical columns

Detached ADU? Max ADU % Front / side / rear setbacks Min lot Height

To validate · column set to be locked with Scott's translator

Same fields everywhere, different zoning-code rows per market. That is what makes a single shared rules table possible, and it is why exact-string matching has to be replaced by a normalized district key.

06 · Product Vision

Two products, four surfaces, one engine.

Almost two different tools, same data. The recommended sequencing is homeowner-on-site as V1, realtor as V2, off the same shared backend.

Shared capability · proposed

Zoning rules + server verdict engine

Approved rules, normalized district matching, one authoritative evaluation, exposed through a shared API.

Product · recommended V2

Realtor data service

Standalone and brandable: any address in, what can be built there out. Reads as a utility, with Compact Cottages surfacing as the recommendation rather than the pitch.

Product · recommended V1

Homeowner ADU tool

"Can I build an ADU?" answered with eligibility, size and the model that fits. The Compact Cottages conversion experience, on-site and already scaffolded.

Chatbot ADU flow

Eligibility answered inside the existing chat, through the same API.

Per-listing zoning cards

A zoning summary attached to each land listing.

Additional surfaces

Anything else that can consume one shared verdict.

Recommendation · not yet approved

Today · what a visitor gets

ZoningRM8
Detached ADUAllowed
Front / side / rear15 / 6 / 15 ft
Max ADU≈ 530 sq ft

Correct, but it reads like a permit-office printout.

Proposed · a plain-English verdict

"Yes, you can build a detached ADU up to about 530 sq ft in your backyard."

Eligibility. Allowed by right in this district.

Approximate size. Up to about 530 sq ft.

Caveat. A preliminary estimate, not a permit or legal determination.

Matching model. The Origami Home (384 sq ft) fits your lot.

Next action · Start a study · $650

07 · Target Architecture

One system map: two paths, one dataset, one verdict.

Authoring rules and answering a lookup are separate paths that meet at the approved rules. Reading them as a single pipeline is what hides the human-approval step.

System board · authoring path and lookup path

Solid: settled · dashed: to validate · dark: not built

Path A · authoring

Runs offline, per market

Published county ordinance / UDO

The source document. Most are online.

AI drafts structured rows

A drafting assistant. It proposes values and cites the ordinance section for each one.

Proposed · AI-assisted, never authoritative

Scott reviews and approves

The mandatory gate. Nothing reaches a customer unapproved.

Human in the loop · required

Editable rules source of record · Zoho

One row per zoning type by county, shared columns, county-filtered views. Scott edits it the way he edits projects today.

Recommended · to validate Wed, August 19, 2026

Path B · live lookup

Runs per request

Address entered

From any surface: site, widget, chatbot, listing card.

Parcel lookup

Lot size, existing home, zoning district code.

Verified today · keep

Normalized district key

Replaces exact-string matching. Unknown input returns an explicit safe state instead of a blank screen.

Proposed · closes a verified gap

Waits for nothing upstream

A lookup never queries the authoring path. It reads the served dataset below.

↓ sync · approved rules only

↓ reads · per request

Where the two paths meet

Approved zoning rules, served from the fast store

Parcels and approved rules sit in the same DigitalOcean store, so a live lookup queries one place. Sync performance is still to validate.

Parcels · verified Approved rules · proposed

The missing layer

Proposed · newly introduced

Server-side verdict engine

1 · Allowed uses

Read from the approved rules for that district.

2 · Maximum ADU size

Parcel inputs run through the district formula.

3 · Matching cottage model

The model that fits the allowed footprint.

One authoritative evaluator, replacing the browser computation and the second admin evaluator. Customer-facing and administrative answers can no longer drift apart.

Shared API

One contract, one verdict, every surface.

Homeowner ADU tool

V1 recommended

Realtor utility

V2 recommended

Chatbot ADU flow

Same API

Listing zoning cards

Same API

08 · Validation & Launch Gates

Eight gates. None of them are closed yet.

Every open risk in this briefing, in one place. A gate is only marked complete when the evidence says it is complete.

Actual loaded-market coverage

Earlier understanding suggested Buncombe only; the calls referenced Raleigh, Durham, Henderson, Orange, Asheville and Buncombe test sets. Confirm the actually-loaded datasets before promising coverage.

To validate

Needs verification · not resolved in this brief

Rules source-of-record and sync/cache performance

Querying two sources live, raised Aug 17. The recommended sync is drawn in 07. Still an engineering call.

Recommended · to validate

Wed, August 19, 2026 · Scott

District normalization must eliminate silent failures

Exact-string matching currently returns nothing on casing or spacing drift. Unknown or unsupported data must produce an explicit safe state.

Proposed · required in build

Verified defect today

AI-drafted rules require citations and human approval

Drafts must cite the UDO section, and Scott approves per county. AI never decides a zoning rule.

Recommended guardrail

Direction to confirm

One authoritative server-side evaluator

The browser computation and the second admin evaluator must be replaced by a single evaluation path.

Proposed · required in build

Divergence verified today

Public read/API exposure and authentication

The read API is public and unauthenticated. The exposure and authentication approach needs review before a branded or public rollout.

Launch blocker · must fix before launch

Verified today

Default credentials, fallback secret, role controls

Admin password resets to a default on boot, a hard-coded fallback secret exists, and there are no role checks: any logged-in viewer can rewrite the rulebook.

Launch blocker · must fix before launch

Verified today

Preliminary-estimate framing on every public result

Every surface states that results are preliminary estimates and not legal or permit advice, the framing already established in this briefing.

Recommended · required at launch

Established in this brief

09 · Decisions Required

What we should walk out of the two calls having settled.

Engineering questions for Scott on Wednesday, August 19, 2026. Strategic decisions for Steve and Barry on Thursday, August 20, 2026. Each recommendation below is a recommendation only.

Engineering · Wednesday, August 19, 2026 · with Scott

Where do the rules live: Zoho, or Postgres behind an editable admin?

Current recommendation

Zoho as the human-editable source of record, with a sync/cache into DigitalOcean so lookups hit one fast store.

Must be confirmed

Whether Zoho serves and syncs at scale, and what the refresh mechanism is.

To validate

How do we standardize columns across jurisdictions?

Current recommendation

Use Scott's cleaned zoning translator to define the canonical column set; rows stay per-jurisdiction.

Must be confirmed

The final field list, and how districts that don't fit the shared columns are handled.

To validate

What coverage is actually live today?

Current recommendation

Confirm loaded datasets before promising coverage. Growth focus is Durham–Raleigh.

Must be confirmed

Which of the referenced markets are loaded versus test sets. Listed as gate 1 in 08.

To validate

What guardrails apply to AI-drafted rules?

Current recommendation

The guardrails in gate 4 of 08: cited drafts, per-county approval, preliminary-estimate framing on every surface.

Must be confirmed

The approval record and what happens when an ordinance changes.

Decision required · direction

Strategic · Thursday, August 20, 2026 · with Steve & Barry

Priority user: homeowner upsell on-site, or standalone realtor tool?

Current recommendation

Build the shared backend and verdict first, since both products need it. Ship the homeowner ADU tool on-site as V1, then the standalone realtor utility as V2 off the same API.

Must be confirmed

Which user comes first, and which capabilities matter most to them.

Decision required

Budget, timeline and developer sourcing.

Current recommendation

Lock scope Thursday, draft scope and initial quotes, then begin the senior developer search. The rebuild comes in-house to Rowan.

Must be confirmed

Budget and timeline are not yet locked; developer sourcing is not yet decided.

Decision required

Green-light the direction: rules-as-data plus one server verdict layer.

Current recommendation

Approve the architecture direction in 07 subject to Wednesday's engineering validation, and approve starting the developer search.

Must be confirmed

That the direction is approved as scope, and which launch gates must close before any branded release.

Decision required

10 · Developer Handoff

The build contract, without reading the rest.

Scope extracted from the sections above. Outcomes are stated as testable results, not as implementation instructions.

Keep / reuse

The existing DigitalOcean parcel backend: Postgres, CSV upload, versioning and activation.

Fast address and PIN search.

The existing code and API as reference. Port the good parts.

Build / rebuild

The structured rules model with shared canonical columns.

The rules publishing and sync workflow.

Normalized district matching.

One server-side verdict layer.

The shared API capability.

Plain-English result UX and the required product surfaces.

Validate

The eight gates in 08, each with its owner and status.

Nothing here is a build task until its gate closes.

Fix before public launch

The three issues verified in 04: a public unauthenticated read API, default admin credentials with a hard-coded fallback secret, and missing role checks on rule editing.

Gate conditions in 08.

Inputs required

Repository, backend and admin access.

Scott's cleaned zoning translator.

Confirmed loaded markets.

The priority-user decision.

Approved direction and scope.

Acceptance outcomes · testable, implementation-agnostic

An address reliably resolves to a normalized zoning district.

Approved rules can be updated without rebuilding application logic district by district.

The customer-facing and administrative results use one authoritative evaluation path.

A covered property returns permitted-use information, an ADU-size result where applicable, and a matching cottage recommendation through a shared backend capability.

A new market can be demonstrated end to end: AI draft → human review → approval → publish and sync.

Unauthorized users cannot modify the production rules dataset.

Unknown or unsupported data produces an explicit safe state, never a silent blank or a fabricated verdict.

11 · Rollout Plan

Five phases, gated by one proof.

The rebuild comes in-house to Rowan. Nothing after phase 3 starts until one new market has been proven end to end.

01

Analyze

Confirm the data flow, schema and true coverage. Largely done. This briefing and the research docs are the head start.

Mostly complete

02

Architect

The system board in 07, specced and costed.

Pending Wednesday validation

03

Prove one new market

End to end, on the real workflow: AI draft, human approval, publish, sync, verdict. The gate for everything after it.

Phase gate

04

Homeowner V1

The ADU verdict experience on the Compact Cottages site, off the shared backend.

Recommended sequencing

05

Realtor V2 & surfaces

The standalone realtor utility, plus the chatbot ADU flow and per-listing zoning cards, all on one backend.

Recommended sequencing

Immediate gates

This week

Brief ready

This briefing, the master proposal and the developer brief prepared.

Wed, August 19, 2026 · 3:00 PM

Backend deep-dive

Walk the backend with Scott; settle the rules columns and the sync approach.

Thu, August 20, 2026

Direction lock

Steve validates the priority user and direction; green-light scope.

Then

Scope, quotes, sourcing

Draft scope and initial quotes; begin the senior developer search.

Appendix

Evidence behind the briefing.

Anticipated questions

Are we throwing away the existing tool?

No. Columns 01 and 02 of the swap board in 02 stay exactly as they are; enough of the upload tools are functional. The rebuild is the rules layer, the missing server-side lookup and the front end.

Why does the same RM8 district give two different answers?

Same rulebook, different parcel inputs. Worked through in 03.

If rules move to Zoho, won't lookups get slow querying two places?

No, because a lookup never queries the authoring store. The recommended sync is drawn in 07: rules are edited in one place and served from another. Still to validate.

Can AI really fill in zoning rules? Isn't that risky?

AI drafts from the county's published ordinance; it does not decide. Scott validates and approves every county before it goes live, and every result is framed as a preliminary estimate rather than legal advice. The change is from typing hundreds of cells to reviewing a drafted table.

How is this different from what Scott does in the spreadsheet today?

Same content, structured and reusable. Today the spreadsheet feeds a developer who hard-codes it into the app, and a data upload can force redoing rules. In the proposed model the approved table is the rules: edited once, synced live, reused by every surface, and AI-drafted for new markets.

What do you need from us to move?

The inputs listed in 10: repository and backend/admin access, Scott's tidied translator, the priority-user decision and confirmation of which markets are actually loaded. Then scope and quotes, and developer sourcing.

Worked numbers · from the live tool

178 Fairfax Ave, Asheville · RM8: existing approximately 760 sq ft home on a 0.26-acre lot; detached ADU allowed, maximum approximately 530 sq ft; the Origami Home (384 sq ft) fits.

1717 Old Haywood Rd, Asheville · RM8: vacant, ADU maximum 0 with no primary home yet; a build-from-scratch and density story.

ADU-max formula: floor( min(0.70 × heated_living_area, 800) / 10 ) × 10.

Sources & provenance

Full read of the cloned zones-api, zones-admin and zones-site code, cross-checked against the live API.

Aug 10 and Aug 17 Compact Cottages tactical calls (Steve, Barry, Scott).

Scott's translator: 2026-08-11 zoning translator.xlsx (Dropbox · consultant files).

Companion docs: master proposal, developer brief, flow diagram and plain-English explainer.

Preliminary planning briefing: not a permit or legal advice. Compact Cottages × Rowan · 2026-08-18. Quantities marked with "approximately" or "~" are estimates; coverage claims remain pending verification of the loaded datasets.