heavymap

Beta gate: Hamilton (merged G5 + G6, staged, per jurisdiction)

Status: accepted 2026-10-18 (Morgen). Linear: NA-269 (gate definition), NA-29 (reconciliation epic), NA-306 (pre-publish check subsystem), NA-305 (browser notice), NA-304 (OSM, deferred), NA-308 (run-record UI, standing), NA-309 (addresses with no parcel), NA-310 (experience profiles, standing). Scope: the City of Hamilton, Ontario, the first jurisdiction to open. Section 9 records Morgen’s 2026-10-18 decisions. Thresholds, gate rules and size budgets in sections 2, 3 and 6 are ACCEPTED.

1. What the gate is

2. Standardized spine and join checks

Each check runs on every build. Each one writes a value into the run record (section 3). The same definitions apply to every jurisdiction. Only the thresholds may differ, and any difference must be written down.

Notation: City parcels = the authoritative parcel fabric (for Hamilton, the City parcel layer the registry mints from). Attribute fabric = a second parcel fabric joined for identifiers (for Hamilton, NPCA Assessment_Parcels_Test for ARN).

# Metric How it is computed Hamilton today (2026-10-17 run) Threshold (ACCEPTED 2026-10-18)
S1 One-to-one rate Reciprocal representative-point matches between City parcels and the attribute fabric, after the offset is applied. Divided by attribute-fabric parcels in the overlap set. 90,102 pairs, 99.77% warn below 99.5%, fail below 99.0%
S2 One-to-one quality Overlap ratio (IoU) of S1 pairs: p10, p50, p90, and the count with IoU ≥ 0.9. p10 0.999, p50 1.000, p90 1.000; 89,837 at ≥ 0.9 fail if p10 < 0.95
S3 One-to-many and many-to-one Count of City parcels linked to more than one identifier, and identifiers linked to more than one City parcel. Placeholders are excluded (see S5). Recorded in registry arn_links; recount after the batched re-run reported, no fail level; every case has a grade
S4 Unmatched City parcels in the overlap set with no identifier, and attribute-fabric parcels with no City parcel. Recount after the batched re-run ≤ 0.5% each, every one labelled
S5 Placeholder count Identifier values that are sentinels (for ARN, all zeros). Graded placeholder, never one_to_many. 10 links (GAP-0005) any count passes as long as all are flagged; 0 unflagged
S6 Not in coverage City parcels outside the attribute fabric’s footprint. Graded not_in_coverage, tied to the dataset that defines the coverage. 74,276 of 166,745 (GAP-0010) Labelled, no fail level (coverage is a fact about the source)
S7 Offset applied The measured translation between fabrics (median dx, dy), its spread (IQR) and the sample size. The build fails if the offset in use differs from the offset measured on this pull by more than a tolerance. dx +0.297 m, dy −0.939 m, IQR < 3 mm (Q-004, NA-276) tolerance 0.05 m; IQR ≤ 0.01 m
S8 ID stability across runs Between this run and the previous registry: kept, replaced_by, split_into, merged_from, newly minted, retired. On an unchanged input, every ID must be kept. Synthetic test passes; first real repeat pending Unchanged input: 100% kept (hard). Changed input: reported
S9 Overlay link coverage For each overlay layer (zoning, OP designations, conservation and so on): the share of City parcels with at least one link, plus layers present with zero links. 644,398 links over all parcels every layer has ≥ 1 link or a gap entry explaining why not
S10 Sliver counts Links whose area share falls under the sliver rule, per layer. Flagged, never dropped. 150,610 of 644,398 flagged Reported, no fail level (flag, never extinguish)
S11 Address and footprint linkage Addresses inside exactly one parcel, more than one, or none. Footprints the same way. 273,955 addresses, 214,287 buildings registered reported; “none” cases labelled
S12 Row-count drift Rows per source layer against the previous pull. First baseline 2026-10-17 warn at > 2% change, explain at > 5%

Notes on accepted thresholds (Morgen, 2026-10-18):

A check that cannot be computed writes a blank with a reason, never a zero (HARD-RULES 8).

3. Professional practice: independent repeat runs as proofs of work

4. Labelling: every known conflict observed and labelled

Class Example publish_priority
withheld_screened Owner, Legal_Txt must_solve_before_publish (meaning screening must be proven, not that the data is shown)
placeholder ARN all zeros label_and_ship
not_in_coverage 74,276 parcels outside NPCA ARN coverage label_and_ship
stale, sparse 2020 PropCode label_and_ship
contradictory PropCode vs current zoning (count pending) label_and_ship
empty, not_present_in_source PostalCode, tax class label_and_ship
offset (quirk) NPCA 0.984 m shift label_and_ship (already measured and corrected; S7 stays as the guard)
range_gzip (quirk) Firefox + GitHub Pages label_and_ship (browser notice, NA-305)

5. Screening: dataset-origin visibility

6. Pre-publish checks (incremental, NA-306)

Run over every output file of the build, fail closed:

  1. Leak test: no withheld field names or known withheld values in any output.
  2. Schema and allowlist: every emitted field is allowlisted for that output.
  3. Size budgets (ACCEPTED 2026-10-18): startup payload ≤ 50 KB compressed; per-click dossier shard ≤ 50 KB compressed (p95); each .pmtiles ≤ 100 MB; total site ≤ 1 GB (the GitHub Pages limit). Accepted, and flagged as an ongoing optimization need. Future experience profiles that need meta-stamping of back-end elements: standing issue NA-310.
  4. Reproducibility: the repeat-run comparison from section 3.

Later increments: licence and attribution presence, gap-ledger completeness, a cross-browser smoke test, a load test, link checks.

7. Build output shipping

8. Browser notice and sign-off

9. Decisions for Morgen (2026-10-18)

# Question Outcome
1 Accept or adjust each PROPOSED threshold in sections 2, 3 and 6. DECIDED 2026-10-18. All S1–S12 thresholds, the repeat-run gate rule and the size budgets are ACCEPTED. Notes: (a) S9 644,398 is overlay links, not parcels; (b) S11 none-cases need a stable tag and an index (NA-309); (c) S12 drift distinguishes publisher change from a broken pull; (d) size budgets accepted, optimization ongoing (NA-310).
2 Add publish_priority to sheet 20, and create the class register (sheet 21)? DECIDED 2026-10-18. Applied.
3 Confirm the suggested publish_priority values in section 4. DECIDED 2026-10-18. Accepted except NPCA offset: label_and_ship (already measured and corrected; S7 stays as the guard).
4 Where publish_visibility lives: inventory or class register. DECIDED 2026-10-18. Dataset inventory. Values: public / restricted / withheld / internal_only. restricted = paid or unconfirmed licence. Restricted list is gitignored; public files mention only that the list exists. Future private ia-restricted repo.
5 The withheld_disclosure default: manifest_entry or none. OPEN. Interim default manifest_entry, marked interim. Section 4 does not imply a close.
6 Whether, and how, a parcel dossier signals held identifying information. DECIDED 2026-10-18. Yes, dossiers will signal held identifying information. Wording is tied to logged-in and paid tiers (front-end and business).
7 Relax HARD-RULES rule 3 so the deploy pipeline can be built before the gate opens. DECIDED 2026-10-18. Tooling may be built and tested. Public publish or deploy still needs Morgen’s per-jurisdiction sign-off (NA-269).
8 Is run 3 required on a different machine, or is a fresh container on Deb enough? DECIDED 2026-10-18. Run 2 and run 3 on Deb. Run 3 in a fresh isolated container on Deb. Cursor VMs cannot run it until inputs live in private storage.
9 How much of the run record is public. DECIDED 2026-10-18. Full run record, screened. Front-end element: standing issue NA-308. Linear label standing marks near-permanent maintenance-class issues.
10 When to split universal back-end publishing into a separate industrial-atlas repo. DECIDED in principle 2026-10-18, timing pending Morgen confirmation. Keep everything in this repo for now. Move the back end to industrial-atlas as soon as practical, leaving heavymap (local and GitHub) dedicated to the front end.