Status: architecture sketch, 2026-09-23, vacant-display nuance 2026-10-17. Linear NA-11. Docs only.
The contract is the rule for anything the ladder says about a spine unit. A presentation may assert a fact only with an evidence grade and a source stamp. Where it cannot assert, it records a refusal. Silence is not a value.
The contract exists because a gap that looks like a measurement will be read as a fact about land and about the people on it. The Hamilton–Niagara prior art already hit this: a missing employment denominator rendered as zero reads as an empty site.
derived_readings header is named here so later rows use it consistently.refused with one reason. The ladder does not have a third, silent state.Every filled value has one grade:
| Grade | Plain meaning |
|---|---|
observed |
Copied from a source and normalised. Not interpreted. “The by-law text says L1.” |
joined |
An observed value placed on this spine key by a named join method. The method is part of the stamp. |
derived |
Computed from named inputs by a named method. A reading, not a new observation. |
refused |
No assertion. A reason code is required. There is no grade that means “probably empty.” |
joined is not more true than observed. It records an extra step that can be wrong. A point-in-polygon zoning code is joined. The by-law’s own polygon id, if HeavyMap ever held it as the unit itself, would be observed.
Join methods, carried on the stamp when the grade is joined. Names follow the prior-art set; this sketch does not re-specify tolerances:
| Method token | Reader takeaway |
|---|---|
identifier |
The source’s own id matched. |
normalized_address |
Address text matched after normalisation. Some rows of that table will have failed. |
point_in_polygon |
A point of this unit fell inside a published polygon. |
containment |
Geometry of this unit sits inside the source geometry. |
proximity |
Nearest feature under a stated distance. The distance is not access. |
overlap |
Area overlap above a stated threshold. |
A stamp is the smallest set of fields that lets someone else find the same record.
| Field | Required |
|---|---|
source_name |
Yes |
publisher |
Yes |
licence |
Yes. If the refusal is not_licensed, the stamp names the product that was not used. |
original_id |
Yes when the source has one. |
retrieved_on |
Yes for anything HeavyMap holds. The date the file was obtained. |
observation_on |
Yes. The date the source’s fact refers to. A by-law adopted in 2017 and retrieved in 2026 keeps both dates. |
join_method |
Yes when grade is joined. |
inputs and method |
Yes when grade is derived. |
note |
When a trap matters (layer index, unit of measure, address restyling). |
The original published value survives next to any normalised one. A New York floor area stays in the published square feet on the stamp even if a reading also states square metres.
A claim may carry a joining-concept id beside the publisher’s field name. The id names the job. The field name stays as published. The concept does not add a ladder band.
The closed sets for relation, authority scale, claim grain, register family, and ledger evidence level, and the thirty concept ids, are in ADR 0002. Federal registers stay on the bands they already belong to, and carry an authority scale when a later slice writes that field. The source-stamp table above is unchanged. Counts for a whole jurisdiction (jurisdiction_activity_aggregate) are not claims about a spine unit. Parcel-level refusal for that object is not_in_coverage.
A refusal uses exactly one of:
| Reason | Use it when |
|---|---|
not_in_coverage |
The layer, jurisdiction, or vintage is outside what v1 holds, or the responsible publisher does not release that object. Geography outside the v1 list is this reason. A city with no public parcel fabric is this reason for parcel grain. |
not_licensed |
A source exists and HeavyMap is not allowed to use it. (MPAC was the standing example until HARD-RULES 4 was amended on 2026-10-17; it is no longer refused on licence.) |
not_joined |
A usable source is in hand, or is expected in the joined set, and this key has no accepted join yet. |
One reason only. If a layer is both unlicensed and unjoined, not_licensed wins: there is nothing to join. If a layer was never in the v1 set, not_in_coverage wins: do not imply a join is the remaining step.
Words that may appear only as a quotation of a source’s own classification or register, with grade observed or joined and a stamp:
HeavyMap must not assert on its own that land is vacant. It may display the source’s class, quoted and attributed. Examples of allowed display (not final UI copy):
City class: Vacant Lands — Hamilton Existing Land Use PRIMARY_LA value, labelled as the City’s classUI naming conventions for surfaced source classes will be refined later.
Display pattern, not final copy: an MPAC tax or property class (public in Ontario, HARD-RULES 4) may be surfaced as a cross-confirmation signal such as Tax class confirmed: industrial.
Without that quotation they are forbidden, including as friendly summaries of a refusal. “Not joined” is not “vacant.” “Not licensed” is not “unassessed.” “Not in coverage” is not “no industrial activity.”
Also forbidden:
0 where the quantity could not be computed. The value is refused, and the reason says which input was missing.When two stamped records disagree, both stay, grades and stamps intact, and the assertion is contested. When a later check knocks down an assertion, the state is refuted and both the assertion and the refutation remain visible. Deleting the contested line would hide the disagreement. Allowed assertion states are supported, contested, and refuted. A refusal is not one of those states. Most units will have no assertion beyond their observed attributes, and that is a normal filled ladder, not a thin one.
A derived reading is grade derived. It names its inputs, its method, and its unit. It lives on the derived_readings rung. If an input is refused, the reading is refused with that input’s reason. Confidence does not fill a refused reading.
MCS Part 2 column derived_readings is a dataset field. It lists reading identifiers that dataset is allowed to feed, |-separated. It uses reading names, not ladder tokens. The ladder token derived_readings must not be written into this column; that token belongs in dossier_bands.
An empty derived_readings cell means “this dataset feeds no reading.” It does not describe a parcel, and it must not be copied onto a unit as vacancy.
Illustrative reading identifiers, not a closed catalog:
| Identifier | Kind of method | Typical refusal |
|---|---|---|
floor_area_m2 |
Convert published floor area to square metres; keep the source unit on the stamp | not_in_coverage when no floor area was published |
employment_interval |
Carry a published employment band as a range | not_in_coverage where no employment register exists |
coverage_ratio |
Building footprint area divided by parcel area | not_in_coverage or not_licensed when parcel area is missing; never 0 |
A new identifier may be added when a reading is specified. It needs a method someone can re-read. It does not need a UI.
These are the same illustrations as in PCDP.md. They show the contract, not real parcels.
hm:ca:on:welland:footprint:SYN-0142Filled claim, grade joined.
land_useL1 — Light Industrial (synthetic)original_id SYN-ZONE-L1; join_method point_in_polygon; retrieved_on and observation_on both marked illustrative, and not the same kind of date if a real by-law is later joined.Filled claim, grade joined, weaker method available and rejected.
activity_registersnei_id SYN-8130 present on this footprint (synthetic)join_method identifieremployment_interval), grade derived only after the observed band is on the stamp.Refusals on the same unit.
| Object | Reason | What a reader must not conclude |
|---|---|---|
| Parcel polygon | not_in_coverage |
That Welland has no lot here |
| Assessed value (not yet joined from MPAC) | not_joined |
That the land is unassessed |
constraints rung |
not_joined |
That the site is unconstrained |
coverage_ratio |
not_in_coverage |
That coverage is zero |
hm:us:ny:erie:parcel:SYN-999.00-1-1.1Filled claim, grade observed.
land_use710 (synthetic)original_id SBL SYN-999.00-1-1.1; observation_on the roll year of that extract.Filled reading, grade derived.
derived_readingsfloor_area_m220000 square feet (synthetic)0.092903Refusals on the same unit.
| Object | Reason | What a reader must not conclude |
|---|---|---|
| SWIS / city or town name | not_joined |
That the parcel is “county land” with no municipality |
constraints rung |
not_in_coverage |
That no overlay applies in the world |
activity_registers rung |
not_joined |
That the site is inactive or vacant |
Owner name is not a v1 ladder object, so the presentation has no owner field and no fourth refusal code. A later decision that allows an owner claim has to bring it in with a grade and a stamp.
The American activity refusal and the Canadian constraints refusal are the same kind of event in the contract: a named inability to speak. The land-use claims beside them are a different kind of event, and they do not fill the refused rungs by implication. A manufacturing property class does not prove a permit. A light-industrial zone does not prove a tenant.
first-attempts/niagara-atlas/DOSSIER-TECHNICAL-REPORT.md — attributed, dated, bounded, refusable; null is not zero; contested records both stay; “vacant” reserved for a register’s own word. Those rules are the pattern this contract keeps.first-attempts/niagara-atlas/README.md — provenance travels with the feature; observation is not inference; a derived score is an indicator.first-attempts/niagara-atlas/INTEGRATION.md — uneven coverage across Hamilton, Niagara Region, Erie, and Niagara County NY is a publishing fact. The map’s job is to say so.babbworks/atlas) — derived indicators live in a scoring step separate from source modules. Beta may copy that separation. It does not copy UK geographies, UK ports, or UK scores.