Skip to main content
Contact us

Case study · Public interest / housing and mobility

Where can I lawfully sleep tonight? One question, answered with its sources attached

FreeCamps is a National Digital product. It publishes where you can legally stay overnight in Australia, with every legal claim traced to an official source, quoted exactly and dated.

National Digital delivers platform engineering for public-records sites that have to stay correct unattended.

Last updated

Technologies

  • Node.js
  • JavaScript
  • MapLibre
  • Model Context Protocol
  • Cloudflare Pages
  • GitHub Actions
✓ Verified Review

“The load-bearing decision in FreeCamps is that unknown is rendered as unknown. Every New South Wales council page says so, because the state keeps no register of local laws, and rest areas are held back because their publisher never set a licence. A site that always has a confident answer is the one that gets somebody moved on at midnight.”

Cameron Young CEO at National Digital

2,770

Pages, each built from a pinned official snapshot

127

Legal claims, each with a source, a quote and a date

862

Rest areas withheld because the licence does not permit republishing

4

Tools on the MCP server

At a glance

Industry
Public interest / housing and mobility
Engagement type
In-house product
First release
2026
Team
National Digital engineering team

The challenge

Overnight-stay law differs by state and by council, is published in incompatible formats by dozens of agencies, and is easy to over-read. A reader acting on a wrong answer is moved on at midnight or fined, and the people who most need the answer are the least able to absorb either.

What we built

A static generator over pinned official snapshots, with every legal claim gated on provenance: a source URL from an official-domain allowlist, an exact quote, a retrieval date and a re-verification deadline, enforced in the build and not in review. The same records are served to AI assistants through an MCP server.

  • A claims register: each legal statement carries an official source, exact quote, retrieval date and re-verification deadline
  • Fail-closed licensing, so an unrecognised or missing licence makes a snapshot unpublishable
  • Per-jurisdiction template modules, because the law differs in kind and a shared template would blur it
  • Composed place titles from a field-entered source, with collisions resolved against the whole set
  • A static generator with no package dependencies, MapLibre and fonts vendored, and no CDN at build or run time
  • A read-only MCP server that answers from the same records, with every statement's source and quote

The stack

A Node generator that imports only Node builtins; MapLibre and font subsets vendored; per-jurisdiction template modules so one state's rule is never written in another state's voice; a fail-closed licence allowlist over every snapshot; a monthly refresh that opens a pull request only when the data changed; and a read-only MCP server on Cloudflare Pages Functions.

DeliveryStatic HTML, maps as enhancement, MCP server

GeneratorNode builtins only

Claims registerSource, quote, date, deadline

Pinned snapshotsOne source per jurisdiction

Gates & refreshFail-closed licensing, monthly PR

The outcome

The build produces 2,770 pages across every state and territory, with national showers and libraries directories and a finder of 2,328 places. 862 rest areas in the Northern Territory and Victoria are deliberately not shown. Their publisher set no licence, the allowlist fails closed, and the pages say so rather than quietly omitting them. Every New South Wales council page reads unknown, because the state keeps no register of council local laws and a confident answer would be invented.

Where it went next

The site is built to run for years on close to no attention. It builds only from committed snapshots, so a government API outage can delay a refresh but never break a deploy, and the monthly refresh asserts row counts because a zero-row success is the classic silent failure. There are no accounts, no user content and no comments.

This case study describes a live product designed and built by National Digital. Counts are taken from the build of the product's main branch on 31 October 2026. The site publishes legal information, not legal advice, and on-ground signage overrides every published page.

Key Takeaways

Engineering a legal-information site that stays correct unattended

  • Legal claims are gated by the build, and reviewer discipline is not relied on.Critical

    The claim gate fails the build on a missing source, an off-allowlist domain or a quote that no longer matches, and the template helper throws if a page renders an unverified claim as fact. Staleness is reported rather than fatal, and the retrieval date is printed on the page.

  • Licensing fails closed, so an unlicensed snapshot is unpublishable rather than accidentally published.Critical

    An allowlist names the licences that permit republishing. Rest areas in two jurisdictions are held because their publisher set no licence string, and the pages name the gap. Everything downstream is still built and tested, so restoring them is one field in a snapshot.

  • Each jurisdiction gets its own template, because the law differs in kind and a shared one would blur it.Critical

    Queensland publishes a rule permitting a fatigue stop unless signed otherwise, and New South Wales guidance says you must not camp in rest areas. The page mechanics are shared and the prose is not, so a reader is never given one state's framing for another's law.

  • A generator with no package dependencies is a maintenance decision with a security benefit.Important

    The generator uses Node builtins only and vendors MapLibre and the fonts, so there is no dependency queue to service, no CDN to trust and no framework migration waiting. The site is judged by what breaks when nobody is watching.

  • Refresh is a reviewed pull request that asserts row counts, never an autonomous write.Important

    A monthly workflow pulls each source, asserts the row count is plausible, rebuilds, and opens a pull request only when the data changed. A zero-row success is the classic silent failure in this class of system, so it is checked rather than trusted.

FreeCamps publishes Australian overnight-stay law as static pages built from pinned official snapshots. Legal claims carry their source, quote and date and are gated in the build, unlicensed data is withheld, and unknown is always rendered as unknown.

Questions about FreeCamps and how it was built

How do you stop a legal-information site like FreeCamps from drifting out of date?

Every legal statement lives in a claims register with the official source URL, the exact quote, the date it was retrieved and a deadline to re-verify it. A build gate fails on a source outside the official-domain allowlist or a quote that no longer matches. Staleness past a deadline is reported rather than fatal, and the retrieval date is printed on the page, so a reader can see how old the answer is.

What happens when a government publisher forgets to set a licence?

The data is not published. An allowlist names the licences that permit republishing and it fails closed, so an unrecognised or missing licence string makes a snapshot unpublishable. That is the live case for 862 (case study) rest areas in the Northern Territory and Victoria, and their pages name the omission rather than showing a shorter list.

Does FreeCamps have an MCP server for AI assistants?

Yes. The read-only MCP server at freecamps.au/mcp has 4 (case study) tools. They find the nearest rest areas, state the rules for a state, territory or council area with each statement's verbatim quote, find public showers and libraries, and list help for tonight. Each answer carries its source, and an unread council is reported as unknown.

What stack does FreeCamps run on?

A Node.js generator written in JavaScript builds static HTML from committed JSON snapshots. It imports only Node builtins, and MapLibre and the fonts are vendored. Cloudflare Pages serves the site and the MCP server, and GitHub Actions runs the tests and the monthly data refresh. Each choice was made to keep the site running with close to no attention.

Why not one parameterised template for every state?

Because the law differs in kind and not only in its values. Queensland publishes a rule that permits a fatigue stop unless signed otherwise. New South Wales driver-fatigue guidance says you must not camp in rest areas. A shared template would encourage writing one state's rule in another state's voice, so the page mechanics are shared and the prose is not.

How does FreeCamps handle a question the records cannot answer?

It says unknown, and unknown is never rendered as permission. Every New South Wales council page reads unknown because the state keeps no register of council local laws. The pages are still published, because one thing is verifiable state-wide, and a test fails the build if the sentence that bounds that claim is removed.

Why build the FreeCamps generator with no dependencies?

The design goal is to run for years on close to no attention, so every choice is judged by what breaks when nobody is watching. No dependencies means no upgrade queue, no supply-chain surface and no framework migration. The site also builds only from committed snapshots, so a government API outage can delay a refresh and can never break a deploy.

Does FreeCamps hold any user data?

None. There are no accounts, no user content and no comments, so there is nothing to moderate, no personal information held and no abuse surface. That is the same decision as the product principle, which is to publish rules and never crowd-sourced spots.

More of our own products

What's next

Claims you have to stand behind?

FreeCamps holds every legal statement to a source, a quote and a date, and fails the build when one drifts. If your product makes claims someone will act on, see how we approach platform engineering, data analysis and insight platforms and custom web applications.

Want a platform like this for your business?

Tell us what you're building. We'll come back within one business day with what we'd do first and what it would take.