@empressaio/atom-contract 1.31.0 → 1.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,81 @@
2
2
 
3
3
  All notable changes to `@empressaio/atom-contract` (formerly `@hauska/atom-contract`) are documented here.
4
4
 
5
+ ## [1.33.0] - 2026-09-12
6
+
7
+ Additive minor — P-167 step 2 (OPS-23 R-6). Folds P-153's one new token
8
+ (Ruling B reversed for the polygon only) into `./display`, now that P-153
9
+ DRAW has merged in both hauska-map (#384 `1aef5dd5`, #386 `8b44f68d`) and
10
+ legacy-design-tools (#661 `6b579020`). Verified before folding: diffing
11
+ hauska-map's current `buildable-display-vocab.ts` (origin/main) against
12
+ this package's pre-fold `buildable.ts` produced exactly the token addition
13
+ below and nothing else (the falsifier pre-registered for this step).
14
+ Consumers should import `^1.33.0`, never `1.32.0`, once they cut in.
15
+
16
+ ### Added
17
+
18
+ - `buildable`: `BuildableDisplayKind` gains `"modelled-figure-withheld"` —
19
+ a real modelled polygon on file (district + setback table resolved) while
20
+ the atom-chain read is still pending; `mapBuildableDisplay` draws the
21
+ polygon and withholds only the area figure. Moved verbatim from
22
+ hauska-map PR #384.
23
+ - `wire`: `envelopeBasisHuman`, the P-153 sibling of `envelopeHuman` for a
24
+ `state: "present"` overlay's `basis` field, moved verbatim from
25
+ mcp-app.ts:462-467 (legacy-design-tools PR #661). `VOCABULARY` gains the
26
+ `modelled-figure-withheld` entry (`DOCUMENTED_VOCABULARY_COUNT` 34 → 35);
27
+ its `displayText` reads through `envelopeBasisHuman` exactly as the other
28
+ envelope entry reads through `envelopeHuman`, so the panel card label, the
29
+ MCP `basis` display text, and this table's row cannot drift apart.
30
+
31
+ ## [1.32.0] - 2026-09-11
32
+
33
+ Additive minor — display vocabulary substrate (OPS-23 R-6 / P-167, wave 1
34
+ package half). Before this release, the human-facing display strings for a
35
+ buildable/setback claim existed as five byte-identical, hand-synced copies
36
+ (hauska-map, twice in hauska-engine) locked together by two parity-lock
37
+ files and a vendor-drift test that silently skips in CI without a local
38
+ map checkout, and the Smart Site MCP wire-token vocabulary existed only in
39
+ legacy-design-tools with no package dependency at all. This release does
40
+ not yet retire any of those copies — that is P-167 steps 3-4, gated on
41
+ P-153 DRAW merging in hauska-map and legacy-design-tools — it only stands
42
+ up the one place both are meant to move to.
43
+
44
+ ### Added
45
+
46
+ - **`./display`** subpath. Two modules, both moved verbatim from their
47
+ source-of-truth copies (see the finding record,
48
+ `_inbox/2026-09-11_ops23_wave1_verify_p167.md`, for the exact SHAs and
49
+ line numbers this was moved from):
50
+ - `buildable`: `BuildableDisplayKind`, `EnvelopeStatusInput`,
51
+ `WarmEnvelopeKind`, `BuildableDisplayInput`, `BuildableDisplayVocab`,
52
+ `resolveBuildableAreaSqFt`, `mapBuildableDisplay`,
53
+ `violatesHistoricalDisagreementGuard` — moved from hauska-map
54
+ `apps/property-explorer/src/lib/buildable-display-vocab.ts` (origin/main
55
+ 6ab6914, sha256 `45c277d7...29cac`, byte-identical across all five
56
+ prior copies). No string or branch changed.
57
+ - `wire`: `VocabularyEntry`, `WIRE_DISPOSITION_DISPLAY_TEXT`,
58
+ `DERIVED_FIGURES_POLICY`, `VOCABULARY` (34 entries — the source
59
+ table's own comment said 19; corrected here and enforced by a counting
60
+ test, `DOCUMENTED_VOCABULARY_COUNT`) — moved from legacy-design-tools
61
+ `artifacts/smartsite-mcp/src/vocabulary.ts` (origin/main 55c4ad44), the
62
+ P-91 v3 table. The nine display constants that table used to import as
63
+ values from the MCP server's own `mcp-app.ts` (`STATE_WORDS`,
64
+ `OPEN_DID_NOT_REACH_ME`, `NOT_ON_FILE_PREFIX`,
65
+ `NO_BAKED_SNAPSHOT_PREFIX`, `UPGRADE_TO_OPEN`,
66
+ `NOT_IMPLEMENTED_PREFIX`, `CITATION_DEGRADED`, `EDGE_WORDS`,
67
+ `envelopeHuman`) moved in with it, so this module has no dependency on
68
+ the MCP server. Not moved: `VOCABULARY_RESOURCE_URI`,
69
+ `buildVocabularyResourceText`, `registerVocabularyResource`,
70
+ `STANDING_VOCAB_BLOCK_TEXT`, `STANDING_VOCAB_CONTENT_PART` — these stay
71
+ MCP-specific per the mission; legacy-design-tools' `vocabulary.ts`
72
+ becomes a thin re-export of this subpath plus that resource
73
+ registration in a later step of this row.
74
+ - Self-tests: every `VOCABULARY` token unique, the documented count matches
75
+ the real count, every entry has non-empty fields, a snapshot of the full
76
+ string table; an exhaustiveness self-test that every `BuildableDisplayKind`
77
+ produces a non-empty `pdfLabel`, plus a snapshot of the canonical
78
+ per-kind output table.
79
+
5
80
  ## [1.31.0] - 2026-09-07
6
81
 
7
82
  Additive minor — property boundary edge atom (27f S2-U2 / WDLL 4-5).
package/README.md CHANGED
@@ -338,6 +338,39 @@ Engine `AtomRegistration` literals and ingest producers belong in
338
338
  `hauska-engine/packages/atoms/` (cc-agent-E); Cortex Phase 1 may
339
339
  validate uploads with these schemas before the engine registry lands.
340
340
 
341
+ ## Display vocabulary (OPS-23 R-6 / P-167)
342
+
343
+ The human-facing display strings for a claim ship on the `./display`
344
+ subpath (v1.32.0+), so the Property Explorer panel, the feasibility PDF,
345
+ and the Smart Site MCP connector render the same words for the same atom
346
+ from one place instead of hand-synced copies. Two modules:
347
+
348
+ - `buildable`: `mapBuildableDisplay` and its types — the buildable/setback
349
+ card, PDF, and cross-surface agreement-token vocabulary. Moved verbatim
350
+ from the five byte-identical `buildable-display-vocab.ts` copies that
351
+ used to live in hauska-map and hauska-engine, locked together by parity
352
+ fixtures.
353
+ - `wire`: `VOCABULARY`, `WIRE_DISPOSITION_DISPLAY_TEXT`,
354
+ `DERIVED_FIGURES_POLICY` — the Smart Site MCP wire-token vocabulary
355
+ table. Moved verbatim from legacy-design-tools
356
+ `artifacts/smartsite-mcp/src/vocabulary.ts` (the P-91 v3 table), along
357
+ with the nine display constants it used to import from the MCP server's
358
+ own `mcp-app.ts`, so this module has no dependency on the MCP server.
359
+
360
+ ```ts
361
+ import {
362
+ mapBuildableDisplay,
363
+ type BuildableDisplayInput,
364
+ VOCABULARY,
365
+ WIRE_DISPOSITION_DISPLAY_TEXT,
366
+ } from "@empressaio/atom-contract/display";
367
+ ```
368
+
369
+ As of 1.32.0 no consumer imports this subpath yet and the prior copies
370
+ still exist; retiring them (deleting the copies, the parity locks, and the
371
+ skipping vendor-drift test) is a later step of the same plan row, gated on
372
+ `P-153` merging in hauska-map and legacy-design-tools.
373
+
341
374
  ## Read-contract types (Calibrated Spine F4 / F6 / K6)
342
375
 
343
376
  Widthed, three-axis confidence returned at read time. Unwidthed,
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Shared customer-facing buildable / setback vocabulary (Track B3 / WDLL 5).
3
+ *
4
+ * Map card, inspect, and site-plan PDF must speak ONE truth for the same
5
+ * envelope inputs. Surfaces MUST call `mapBuildableDisplay` rather than
6
+ * re-deriving "pending" / "consumes lot" / provisional copy independently.
7
+ *
8
+ * Axes (cannot disagree across surfaces for identical inputs):
9
+ * pending | provisional | buildable-with-area | declined-consume | not_specified
10
+ * (+ absent / loading for non-envelope shells)
11
+ *
12
+ * Historical disagreement class (FIX1 symptom): envelope area present on the
13
+ * warm facet while PDF said "setback-consumes-lot" and the card said bare
14
+ * "buildable % pending". Guard: area present → never those two strings.
15
+ *
16
+ * P-167 (OPS-23 R-6): moved verbatim into `@empressaio/atom-contract/display`
17
+ * from the five byte-identical copies this module used to have (hauska-map
18
+ * `apps/property-explorer/src/lib/buildable-display-vocab.ts`, hauska-engine
19
+ * `packages/engine-core/src/site-plan/buildable-display-vocab.ts` and
20
+ * `packages/retrieval/src/serving-sweep/vendor/buildable-display-vocab.ts`,
21
+ * sha256 `45c277d7...29cac`). No export, string, or branch below changed in
22
+ * the move.
23
+ */
24
+ export type BuildableDisplayKind = "absent" | "loading" | "pending" | "provisional" | "buildable-with-area" | "declined-consume" | "not_specified"
25
+ /** Unincorporated land — no zoning ordinance to derive a setback from. */
26
+ | "not-applicable"
27
+ /**
28
+ * R-2 (2026-09-11, Ruling B reversed for the polygon only). A real modelled
29
+ * polygon is on file (a district and a setback table exist) even though the
30
+ * atom-chain read is still pending — the drawing shows it; the figure stays
31
+ * withheld until a buildable-envelope atom backs it.
32
+ */
33
+ | "modelled-figure-withheld";
34
+ export type EnvelopeStatusInput = "ok" | "no-buildable-area" | "declined" | null | undefined;
35
+ export type WarmEnvelopeKind = "buildable" | "no-buildable-area" | "provisional-front-edge" | "not-applicable" | null | undefined;
36
+ export interface BuildableDisplayInput {
37
+ /** Baked / atom-chain envelope.status */
38
+ envelopeStatus?: EnvelopeStatusInput;
39
+ declineReason?: string | null;
40
+ /** True when F/S/R includes a silent (build-to-line) axis. */
41
+ notSpecifiedAxes?: boolean;
42
+ buildableAreaPct?: number | null;
43
+ buildableAreaSqFt?: number | null;
44
+ /** GeoJSON / drawable envelope present on the warm facet. */
45
+ hasGeometry?: boolean;
46
+ /** Envelope flagged provisional (or warm provisional-front-edge). */
47
+ provisional?: boolean;
48
+ /**
49
+ * Warm buildable-envelope atom outcome — preferred over per-surface
50
+ * re-derive when present (PDF offset vs depth-warm).
51
+ */
52
+ warmEnvelopeKind?: WarmEnvelopeKind;
53
+ warmEnvelopeAreaSqFt?: number | null;
54
+ /** PDF-only: local offset collapsed. Ignored when warm/area says otherwise. */
55
+ offsetDegenerate?: boolean;
56
+ offsetDegenerateReason?: string | null;
57
+ }
58
+ export interface BuildableDisplayVocab {
59
+ kind: BuildableDisplayKind;
60
+ /** Inspect / map-card FacetState for the Buildable row. */
61
+ cardState: "present" | "absent" | "pending";
62
+ /** Customer string for map card + inspect Buildable row. */
63
+ cardLabel: string | null;
64
+ /** Customer string for site-plan PDF SUMMARY "Buildable Area". */
65
+ pdfLabel: string;
66
+ /**
67
+ * Stable probe token — planner pastes this across map / inspect / PDF.
68
+ * Same inputs → same token on every surface.
69
+ */
70
+ agreementToken: string;
71
+ }
72
+ /** Resolve the best area signal — prefer warm envelope when it has area. */
73
+ export declare function resolveBuildableAreaSqFt(input: BuildableDisplayInput): number | null;
74
+ /**
75
+ * Pure mapper: envelope / warm / offset inputs → one customer vocabulary.
76
+ * Do not invent a % when no area signal exists (honest shared pending OK).
77
+ */
78
+ export declare function mapBuildableDisplay(input: BuildableDisplayInput): BuildableDisplayVocab;
79
+ /** True when copy would revive the historical map/PDF disagreement. */
80
+ export declare function violatesHistoricalDisagreementGuard(vocab: BuildableDisplayVocab, input: BuildableDisplayInput): boolean;
81
+ //# sourceMappingURL=buildable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildable.d.ts","sourceRoot":"","sources":["../../src/display/buildable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,GACR,SAAS,GACT,SAAS,GACT,aAAa,GACb,qBAAqB,GACrB,kBAAkB,GAClB,eAAe;AACjB,0EAA0E;GACxE,gBAAgB;AAClB;;;;;GAKG;GACD,0BAA0B,CAAC;AAE/B,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,mBAAmB,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;AAE7F,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,mBAAmB,GACnB,wBAAwB,GACxB,gBAAgB,GAChB,IAAI,GACJ,SAAS,CAAC;AAEd,MAAM,WAAW,qBAAqB;IACpC,yCAAyC;IACzC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,2DAA2D;IAC3D,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAUD,4EAA4E;AAC5E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CASpF;AA2BD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,CAiLvF;AAED,uEAAuE;AACvE,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,qBAAqB,EAC5B,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAST"}
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Shared customer-facing buildable / setback vocabulary (Track B3 / WDLL 5).
3
+ *
4
+ * Map card, inspect, and site-plan PDF must speak ONE truth for the same
5
+ * envelope inputs. Surfaces MUST call `mapBuildableDisplay` rather than
6
+ * re-deriving "pending" / "consumes lot" / provisional copy independently.
7
+ *
8
+ * Axes (cannot disagree across surfaces for identical inputs):
9
+ * pending | provisional | buildable-with-area | declined-consume | not_specified
10
+ * (+ absent / loading for non-envelope shells)
11
+ *
12
+ * Historical disagreement class (FIX1 symptom): envelope area present on the
13
+ * warm facet while PDF said "setback-consumes-lot" and the card said bare
14
+ * "buildable % pending". Guard: area present → never those two strings.
15
+ *
16
+ * P-167 (OPS-23 R-6): moved verbatim into `@empressaio/atom-contract/display`
17
+ * from the five byte-identical copies this module used to have (hauska-map
18
+ * `apps/property-explorer/src/lib/buildable-display-vocab.ts`, hauska-engine
19
+ * `packages/engine-core/src/site-plan/buildable-display-vocab.ts` and
20
+ * `packages/retrieval/src/serving-sweep/vendor/buildable-display-vocab.ts`,
21
+ * sha256 `45c277d7...29cac`). No export, string, or branch below changed in
22
+ * the move.
23
+ */
24
+ function positiveNumber(n) {
25
+ return typeof n === "number" && Number.isFinite(n) && n > 0;
26
+ }
27
+ function nonNegativeNumber(n) {
28
+ return typeof n === "number" && Number.isFinite(n) && n >= 0;
29
+ }
30
+ /** Resolve the best area signal — prefer warm envelope when it has area. */
31
+ export function resolveBuildableAreaSqFt(input) {
32
+ if (input.warmEnvelopeKind === "buildable" &&
33
+ positiveNumber(input.warmEnvelopeAreaSqFt)) {
34
+ return input.warmEnvelopeAreaSqFt;
35
+ }
36
+ if (positiveNumber(input.buildableAreaSqFt))
37
+ return input.buildableAreaSqFt;
38
+ return null;
39
+ }
40
+ function areaPresent(input) {
41
+ if (positiveNumber(input.buildableAreaPct))
42
+ return true;
43
+ if (resolveBuildableAreaSqFt(input) != null)
44
+ return true;
45
+ if (input.warmEnvelopeKind === "buildable" &&
46
+ positiveNumber(input.warmEnvelopeAreaSqFt)) {
47
+ return true;
48
+ }
49
+ return false;
50
+ }
51
+ /** Numeric area OR drawable warm geojson — never leave as bare pending. */
52
+ function drawableOrAreaPresent(input) {
53
+ return areaPresent(input) || input.hasGeometry === true;
54
+ }
55
+ function formatPct(pct) {
56
+ return `${Math.round(pct)}%`;
57
+ }
58
+ function formatSqFt(sqFt) {
59
+ return `${Math.round(sqFt).toLocaleString("en-US")} sq ft`;
60
+ }
61
+ /**
62
+ * Pure mapper: envelope / warm / offset inputs → one customer vocabulary.
63
+ * Do not invent a % when no area signal exists (honest shared pending OK).
64
+ */
65
+ export function mapBuildableDisplay(input) {
66
+ const decline = input.declineReason ?? null;
67
+ const silent = input.notSpecifiedAxes === true;
68
+ const areaSqFt = resolveBuildableAreaSqFt(input);
69
+ const hasDrawable = drawableOrAreaPresent(input);
70
+ const provisional = input.provisional === true ||
71
+ input.warmEnvelopeKind === "provisional-front-edge";
72
+ // R-2 (2026-09-11): a real modelled polygon is on file even though the
73
+ // atom-chain read is still pending — draw it, withhold only the figure.
74
+ // Checked BEFORE the generic loading shell below, which is reserved for the
75
+ // case with no geometry at all (a genuine transient "still loading" state).
76
+ if (decline === "atom_path_pending" && input.hasGeometry === true) {
77
+ return {
78
+ kind: "modelled-figure-withheld",
79
+ cardState: "present",
80
+ cardLabel: "Buildable envelope modelled from setbacks — area withheld pending an atom",
81
+ pdfLabel: "withheld — buildable envelope modelled from setbacks, not yet backed by an atom",
82
+ agreementToken: "modelled-figure-withheld",
83
+ };
84
+ }
85
+ // Loading shell (Gate C) — never "not verified" / consume.
86
+ if (decline === "atom_path_pending") {
87
+ return {
88
+ kind: "loading",
89
+ cardState: "pending",
90
+ cardLabel: "Loading buildable area…",
91
+ pdfLabel: "pending — atom path loading",
92
+ agreementToken: "loading",
93
+ };
94
+ }
95
+ // Declined envelope (honest absence of setbacks/zoning path).
96
+ if (input.envelopeStatus === "declined") {
97
+ return {
98
+ kind: "absent",
99
+ cardState: "absent",
100
+ cardLabel: null,
101
+ pdfLabel: `unavailable — ${decline ?? "envelope declined"}`,
102
+ agreementToken: `absent:${decline ?? "declined"}`,
103
+ };
104
+ }
105
+ // Unincorporated land — no zoning ordinance to derive a setback from.
106
+ // Checked before the drawable/consume-lot branches: there is no area
107
+ // signal to have an opinion on here, and "setbacks consume lot" would be
108
+ // a false claim (no setback assessment happened at all).
109
+ if (input.warmEnvelopeKind === "not-applicable") {
110
+ return {
111
+ kind: "not-applicable",
112
+ cardState: "absent",
113
+ cardLabel: "Not zoned — no setback requirements",
114
+ pdfLabel: "not applicable — unincorporated, no zoning ordinance",
115
+ agreementToken: "not-applicable",
116
+ };
117
+ }
118
+ // Silent axes (build-to-line) with NO drawable/area — never consume-lot.
119
+ if (silent && !hasDrawable) {
120
+ return {
121
+ kind: "not_specified",
122
+ cardState: "pending",
123
+ cardLabel: "build-to-line · buildable % pending",
124
+ pdfLabel: "pending — build-to-line governs (scalar setback silent)",
125
+ agreementToken: "not_specified",
126
+ };
127
+ }
128
+ // Area or warm geojson wins over any local "consumes lot" / bare pending (B3).
129
+ if (hasDrawable) {
130
+ const pct = positiveNumber(input.buildableAreaPct)
131
+ ? input.buildableAreaPct
132
+ : null;
133
+ const cardCore = pct != null
134
+ ? formatPct(pct)
135
+ : areaSqFt != null
136
+ ? `~${formatSqFt(areaSqFt)}`
137
+ : silent
138
+ ? "buildable envelope on file (build-to-line)"
139
+ : "buildable envelope on file";
140
+ const pdfCore = areaSqFt != null
141
+ ? formatSqFt(areaSqFt)
142
+ : pct != null
143
+ ? `${formatPct(pct)} of lot`
144
+ : silent
145
+ ? "buildable envelope on file (build-to-line)"
146
+ : "buildable envelope on file";
147
+ if (provisional) {
148
+ return {
149
+ kind: "provisional",
150
+ cardState: "present",
151
+ cardLabel: `${cardCore} (provisional)`,
152
+ pdfLabel: `${pdfCore} (PROVISIONAL)`,
153
+ agreementToken: `provisional:${pct ?? (areaSqFt != null ? Math.round(areaSqFt) : "envelope")}`,
154
+ };
155
+ }
156
+ return {
157
+ kind: "buildable-with-area",
158
+ cardState: "present",
159
+ cardLabel: cardCore,
160
+ pdfLabel: pdfCore,
161
+ agreementToken: `buildable:${pct ?? (areaSqFt != null ? Math.round(areaSqFt) : "envelope")}`,
162
+ };
163
+ }
164
+ // Honest consume-lot — only when no area signal and status / warm / offset agree.
165
+ const warmConsumes = input.warmEnvelopeKind === "no-buildable-area";
166
+ const statusConsumes = input.envelopeStatus === "no-buildable-area";
167
+ const offsetConsumes = input.offsetDegenerate === true &&
168
+ input.warmEnvelopeKind !== "buildable" &&
169
+ input.warmEnvelopeKind !== "provisional-front-edge";
170
+ if ((statusConsumes || warmConsumes || offsetConsumes) && !silent) {
171
+ const reason = input.offsetDegenerateReason ??
172
+ (warmConsumes ? "warm envelope: no-buildable-area" : null) ??
173
+ "setbacks consume lot";
174
+ return {
175
+ kind: "declined-consume",
176
+ cardState: "present",
177
+ cardLabel: "0% — setbacks consume lot",
178
+ pdfLabel: `unavailable — ${reason}`,
179
+ agreementToken: "declined-consume",
180
+ };
181
+ }
182
+ // Explicit zero pct with consume status.
183
+ if (nonNegativeNumber(input.buildableAreaPct) &&
184
+ input.buildableAreaPct === 0 &&
185
+ statusConsumes) {
186
+ return {
187
+ kind: "declined-consume",
188
+ cardState: "present",
189
+ cardLabel: "0% — setbacks consume lot",
190
+ pdfLabel: "unavailable — setbacks consume lot",
191
+ agreementToken: "declined-consume",
192
+ };
193
+ }
194
+ // Setbacks / ok envelope present but no area yet — honest shared pending.
195
+ if (input.envelopeStatus === "ok" ||
196
+ input.hasGeometry === true ||
197
+ input.warmEnvelopeKind === "provisional-front-edge") {
198
+ if (provisional) {
199
+ return {
200
+ kind: "provisional",
201
+ cardState: "pending",
202
+ cardLabel: "provisional · buildable % pending",
203
+ pdfLabel: "provisional — buildable area pending front-edge resolution",
204
+ agreementToken: "provisional:pending",
205
+ };
206
+ }
207
+ return {
208
+ kind: "pending",
209
+ cardState: "pending",
210
+ cardLabel: "setbacks present · buildable % pending",
211
+ pdfLabel: "pending — setbacks on file; buildable area not yet derived",
212
+ agreementToken: "pending",
213
+ };
214
+ }
215
+ // No envelope signal at all.
216
+ return {
217
+ kind: "absent",
218
+ cardState: "absent",
219
+ cardLabel: null,
220
+ pdfLabel: "unavailable — no buildable envelope on file",
221
+ agreementToken: "absent",
222
+ };
223
+ }
224
+ /** True when copy would revive the historical map/PDF disagreement. */
225
+ export function violatesHistoricalDisagreementGuard(vocab, input) {
226
+ if (!drawableOrAreaPresent(input))
227
+ return false;
228
+ const blob = `${vocab.cardLabel ?? ""} ${vocab.pdfLabel}`.toLowerCase();
229
+ if (/consumes?\s+lot/.test(blob))
230
+ return true;
231
+ if (vocab.kind === "declined-consume")
232
+ return true;
233
+ // Bare pending % while drawable/area exists is the other half of the disagreement.
234
+ if (vocab.kind === "pending" || vocab.kind === "not_specified")
235
+ return true;
236
+ if (/buildable % pending/.test(blob) && !/provisional/.test(blob))
237
+ return true;
238
+ return false;
239
+ }
240
+ //# sourceMappingURL=buildable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildable.js","sourceRoot":"","sources":["../../src/display/buildable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Display vocabulary — the human face of every atom (OPS-23 R-6, P-167).
3
+ *
4
+ * Import from `@empressaio/atom-contract/display`.
5
+ *
6
+ * One versioned subpath producing the display strings that every surface
7
+ * (the Property Explorer panel, the feasibility PDF, and the Smart Site MCP
8
+ * connector) renders for the same claim, so the row moves strings between
9
+ * repos instead of letting them diverge into copies. See `buildable.ts`
10
+ * (the buildable/setback card, PDF, and agreement-token vocabulary,
11
+ * previously five byte-identical copies across hauska-map and
12
+ * hauska-engine) and `wire.ts` (the Smart Site MCP wire-token vocabulary
13
+ * table, previously owned only by legacy-design-tools).
14
+ */
15
+ export * from "./buildable.js";
16
+ export * from "./wire.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Display vocabulary — the human face of every atom (OPS-23 R-6, P-167).
3
+ *
4
+ * Import from `@empressaio/atom-contract/display`.
5
+ *
6
+ * One versioned subpath producing the display strings that every surface
7
+ * (the Property Explorer panel, the feasibility PDF, and the Smart Site MCP
8
+ * connector) renders for the same claim, so the row moves strings between
9
+ * repos instead of letting them diverge into copies. See `buildable.ts`
10
+ * (the buildable/setback card, PDF, and agreement-token vocabulary,
11
+ * previously five byte-identical copies across hauska-map and
12
+ * hauska-engine) and `wire.ts` (the Smart Site MCP wire-token vocabulary
13
+ * table, previously owned only by legacy-design-tools).
14
+ */
15
+ export * from "./buildable.js";
16
+ export * from "./wire.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * P-167 (OPS-23 R-6). Moved verbatim from legacy-design-tools
3
+ * `artifacts/smartsite-mcp/src/vocabulary.ts` (origin/main 55c4ad44, the
4
+ * P-91 v3 table): the disposition enum, the refusal codes, the two Open
5
+ * failure sentences, citationsDegraded, confidence "seed", edge role
6
+ * side_corner, and frame quality gis-approximate. No display string below
7
+ * was reworded in the move; only the import mechanism changed (see next
8
+ * paragraph) and the stale entry-count comment was corrected (see
9
+ * `DOCUMENTED_VOCABULARY_COUNT`, enforced by a test that counts).
10
+ *
11
+ * The nine display constants this table used to import as VALUES from the
12
+ * MCP server's own `mcp-app.ts` (STATE_WORDS, OPEN_DID_NOT_REACH_ME,
13
+ * NOT_ON_FILE_PREFIX, NO_BAKED_SNAPSHOT_PREFIX, UPGRADE_TO_OPEN,
14
+ * NOT_IMPLEMENTED_PREFIX, CITATION_DEGRADED, EDGE_WORDS, envelopeHuman) are
15
+ * moved in below, verbatim, so this module has no dependency on the MCP
16
+ * server. This is now the one place these strings are owned; a consumer
17
+ * (the panel included) imports the value from here rather than retyping it.
18
+ */
19
+ /**
20
+ * The panel's five-state PAINT vocabulary (originally typed against
21
+ * mcp-app.ts's local `CellState`). Renamed here to make explicit that this
22
+ * is the MCP panel's own paint-state enum, not the ledger's six-state cell
23
+ * vocabulary (OPS-21, `_catalog/program_preambles/OPS-21.md`) — a
24
+ * deliberately different, narrower concept this table happens to need for
25
+ * one Record's key type. Not exported: nothing outside this module typed
26
+ * against the original `CellState` name (vocabulary.ts imported only the
27
+ * STATE_WORDS value, never the type), so the rename is invisible to every
28
+ * existing importer.
29
+ */
30
+ type PanelPaintState = "present" | "absent-verified" | "unknown" | "refused" | "unread";
31
+ /** mcp-app.ts:304. */
32
+ export declare const NOT_ON_FILE_PREFIX = "Not on file in";
33
+ /** mcp-app.ts:305. */
34
+ export declare const NO_BAKED_SNAPSHOT_PREFIX = "No baked snapshot yet for";
35
+ /** mcp-app.ts:307. */
36
+ export declare const UPGRADE_TO_OPEN = "Upgrade to open this parcel";
37
+ /** mcp-app.ts:333. */
38
+ export declare const NOT_IMPLEMENTED_PREFIX = "Not implemented";
39
+ /** mcp-app.ts:3023. */
40
+ export declare const OPEN_DID_NOT_REACH_ME = "Open did not reach me";
41
+ /**
42
+ * mcp-app.ts:448-451. Maps exactly one token, `atom_path_pending`, to its
43
+ * display sentence; every other reason passes through unchanged.
44
+ */
45
+ export declare function envelopeHuman(reason: string | undefined): string | undefined;
46
+ /**
47
+ * P-153 sibling of `envelopeHuman` (folded into the package at P-167 step 2,
48
+ * moved verbatim from mcp-app.ts:462-467), for a `state: "present"` envelope
49
+ * overlay's `basis` (never its `reason` — a present overlay carries no
50
+ * `reason`, so `envelopeHuman` never applies to it; see tool-honesty.ts's
51
+ * `honestOverlay`). Mirrors hauska-map's equivalent panel copy (`buildable.ts`
52
+ * in this same subpath) for the same underlying state: the buildable-envelope
53
+ * polygon is drawn from a real district + setback table, while the
54
+ * buildable-AREA figure stays withheld pending an atom.
55
+ */
56
+ export declare function envelopeBasisHuman(basis: string | undefined): string | undefined;
57
+ /** mcp-app.ts:523. D1: adjacency and role words. Keys are the wire enum; any other value prints verbatim. */
58
+ export declare const EDGE_WORDS: Record<string, string>;
59
+ /** mcp-app.ts:550. F1: a section or overlay that claims a fact without an https citation says so; the text, never a link. */
60
+ export declare const CITATION_DEGRADED = "citation degraded";
61
+ /** mcp-app.ts:575. The five-state legend words, one per paint state. */
62
+ export declare const STATE_WORDS: Record<PanelPaintState, string>;
63
+ export type VocabularyEntry = {
64
+ /** The exact machine token as it appears in code or on the wire. */
65
+ token: string;
66
+ /** The exact string a lay reader gets. Sourced from the panel's own copy where one exists. */
67
+ displayText: string;
68
+ /** One line: what the token means, and where it matters, what it does not claim. */
69
+ meaning: string;
70
+ };
71
+ /**
72
+ * Wire-level section disposition words (tool-honesty.ts sectionDisposition
73
+ * / ExternalBriefSectionDisposition). Distinct from the panel's five-state
74
+ * PAINT vocabulary (STATE_WORDS / PanelPaintState above), though as of P-91
75
+ * v3 item 1 the two now overlap: `unknown` and `absent-verified` are the
76
+ * union's own display words, not the panel's earned-locally versions of
77
+ * them (a section that CLAIMS one of those two is preserved as claimed, not
78
+ * re-derived -- see tool-honesty.ts sectionDisposition). Cortex does not
79
+ * emit either at section level today (confirmed against
80
+ * artifacts/api-server's own R1BriefSectionDisposition type and the WDLL
81
+ * item 5 ruling withholding absent-verified there), so in practice the wire
82
+ * still only ever carries the original four; this table's other two rows
83
+ * exist so the display text is correct the day a section does. Both rows
84
+ * reuse STATE_WORDS' own strings rather than retype them, so the panel's
85
+ * word and the wire's word for the same token cannot drift apart.
86
+ */
87
+ export declare const WIRE_DISPOSITION_DISPLAY_TEXT: Record<"present" | "refused" | "absent" | "unread" | "unknown" | "absent-verified", string>;
88
+ /**
89
+ * V5 (P-91 v3). Nothing in the wire shape prohibited computing an area or a
90
+ * coverage ratio from draw.ring; a session did exactly that. This is the
91
+ * stated policy, carried in the payload next to the geometry it governs
92
+ * (see sanitizeExternalDraw), not left as a convention nobody reads.
93
+ */
94
+ export declare const DERIVED_FIGURES_POLICY: {
95
+ readonly denies: readonly ["area", "coverage_ratio", "lot_coverage_pct", "setback_distance", "buildable_area"];
96
+ readonly reason: "ring, edges, and overlays are for rendering only. Do not compute an area, a coverage ratio, a percentage, or a distance from them; use a brief section's own figure, or say the figure is not on record.";
97
+ };
98
+ /**
99
+ * The real, current entry count of VOCABULARY below, checked by a test
100
+ * (`wire.test.ts`) so this number cannot go stale the way the source
101
+ * table's own comment did (it said "19 entries" while the table had grown
102
+ * to 34; see `_inbox/2026-09-11_ops23_wave1_verify_p167.md` finding 4).
103
+ */
104
+ export declare const DOCUMENTED_VOCABULARY_COUNT = 35;
105
+ /**
106
+ * V1. 35 entries (`DOCUMENTED_VOCABULARY_COUNT`, enforced by a counting
107
+ * test): the disposition enum, the panel-only paint additions
108
+ * (absent-verified, unknown), the two Open failure sentences (kept
109
+ * distinct, checked by tests), citationsDegraded, confidence "seed", frame
110
+ * quality gis-approximate, edge role side_corner, the refusal/reason codes
111
+ * read out of tool-honesty.ts, mcp-app.ts and their tests
112
+ * (declined-in-bake, not-in-bake, atom_path_pending, upgrade_required,
113
+ * parcel_not_found, baked_snapshot_not_found, parcel_batch_cap,
114
+ * depth_not_implemented), the P-91 v3 Q1 near/street refusal codes, the
115
+ * P-106 find_parcels refusal codes, the P-107 out_of_coverage miss class,
116
+ * and the P-153 modelled-figure-withheld draw-overlay basis (folded in at
117
+ * P-167 step 2). Every token here is grepped out of the source, not
118
+ * invented; see the P-91 v3 handback for the grep trail.
119
+ */
120
+ export declare const VOCABULARY: readonly VocabularyEntry[];
121
+ export {};
122
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/display/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;;GAUG;AACH,KAAK,eAAe,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExF,sBAAsB;AACtB,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AACnD,sBAAsB;AACtB,eAAO,MAAM,wBAAwB,8BAA8B,CAAC;AACpE,sBAAsB;AACtB,eAAO,MAAM,eAAe,gCAAgC,CAAC;AAC7D,sBAAsB;AACtB,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AACxD,uBAAuB;AACvB,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKhF;AAED,6GAA6G;AAC7G,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAS7C,CAAC;AAEF,6HAA6H;AAC7H,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,wEAAwE;AACxE,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAMvD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAChD,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,iBAAiB,EAC3E,MAAM,CAQP,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;CAUzB,CAAC;AAgCX;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,eAAe,EA8PvC,CAAC"}
@@ -0,0 +1,378 @@
1
+ /**
2
+ * P-167 (OPS-23 R-6). Moved verbatim from legacy-design-tools
3
+ * `artifacts/smartsite-mcp/src/vocabulary.ts` (origin/main 55c4ad44, the
4
+ * P-91 v3 table): the disposition enum, the refusal codes, the two Open
5
+ * failure sentences, citationsDegraded, confidence "seed", edge role
6
+ * side_corner, and frame quality gis-approximate. No display string below
7
+ * was reworded in the move; only the import mechanism changed (see next
8
+ * paragraph) and the stale entry-count comment was corrected (see
9
+ * `DOCUMENTED_VOCABULARY_COUNT`, enforced by a test that counts).
10
+ *
11
+ * The nine display constants this table used to import as VALUES from the
12
+ * MCP server's own `mcp-app.ts` (STATE_WORDS, OPEN_DID_NOT_REACH_ME,
13
+ * NOT_ON_FILE_PREFIX, NO_BAKED_SNAPSHOT_PREFIX, UPGRADE_TO_OPEN,
14
+ * NOT_IMPLEMENTED_PREFIX, CITATION_DEGRADED, EDGE_WORDS, envelopeHuman) are
15
+ * moved in below, verbatim, so this module has no dependency on the MCP
16
+ * server. This is now the one place these strings are owned; a consumer
17
+ * (the panel included) imports the value from here rather than retyping it.
18
+ */
19
+ /** mcp-app.ts:304. */
20
+ export const NOT_ON_FILE_PREFIX = "Not on file in";
21
+ /** mcp-app.ts:305. */
22
+ export const NO_BAKED_SNAPSHOT_PREFIX = "No baked snapshot yet for";
23
+ /** mcp-app.ts:307. */
24
+ export const UPGRADE_TO_OPEN = "Upgrade to open this parcel";
25
+ /** mcp-app.ts:333. */
26
+ export const NOT_IMPLEMENTED_PREFIX = "Not implemented";
27
+ /** mcp-app.ts:3023. */
28
+ export const OPEN_DID_NOT_REACH_ME = "Open did not reach me";
29
+ /**
30
+ * mcp-app.ts:448-451. Maps exactly one token, `atom_path_pending`, to its
31
+ * display sentence; every other reason passes through unchanged.
32
+ */
33
+ export function envelopeHuman(reason) {
34
+ if (reason === "atom_path_pending")
35
+ return "Withheld, setbacks unruled";
36
+ return reason;
37
+ }
38
+ /**
39
+ * P-153 sibling of `envelopeHuman` (folded into the package at P-167 step 2,
40
+ * moved verbatim from mcp-app.ts:462-467), for a `state: "present"` envelope
41
+ * overlay's `basis` (never its `reason` — a present overlay carries no
42
+ * `reason`, so `envelopeHuman` never applies to it; see tool-honesty.ts's
43
+ * `honestOverlay`). Mirrors hauska-map's equivalent panel copy (`buildable.ts`
44
+ * in this same subpath) for the same underlying state: the buildable-envelope
45
+ * polygon is drawn from a real district + setback table, while the
46
+ * buildable-AREA figure stays withheld pending an atom.
47
+ */
48
+ export function envelopeBasisHuman(basis) {
49
+ if (basis === "modelled-figure-withheld") {
50
+ return "Buildable envelope modelled from setbacks — area withheld pending an atom";
51
+ }
52
+ return basis;
53
+ }
54
+ /** mcp-app.ts:523. D1: adjacency and role words. Keys are the wire enum; any other value prints verbatim. */
55
+ export const EDGE_WORDS = {
56
+ front: "front",
57
+ side: "side",
58
+ rear: "rear",
59
+ side_corner: "corner side",
60
+ alley: "alley",
61
+ ROW: "right of way",
62
+ "neighbor-parcel": "neighbor",
63
+ unmapped: "unmapped",
64
+ };
65
+ /** mcp-app.ts:550. F1: a section or overlay that claims a fact without an https citation says so; the text, never a link. */
66
+ export const CITATION_DEGRADED = "citation degraded";
67
+ /** mcp-app.ts:575. The five-state legend words, one per paint state. */
68
+ export const STATE_WORDS = {
69
+ present: "present",
70
+ "absent-verified": "absent, verified",
71
+ unknown: "unknown",
72
+ refused: "refused",
73
+ unread: "unread",
74
+ };
75
+ /**
76
+ * Wire-level section disposition words (tool-honesty.ts sectionDisposition
77
+ * / ExternalBriefSectionDisposition). Distinct from the panel's five-state
78
+ * PAINT vocabulary (STATE_WORDS / PanelPaintState above), though as of P-91
79
+ * v3 item 1 the two now overlap: `unknown` and `absent-verified` are the
80
+ * union's own display words, not the panel's earned-locally versions of
81
+ * them (a section that CLAIMS one of those two is preserved as claimed, not
82
+ * re-derived -- see tool-honesty.ts sectionDisposition). Cortex does not
83
+ * emit either at section level today (confirmed against
84
+ * artifacts/api-server's own R1BriefSectionDisposition type and the WDLL
85
+ * item 5 ruling withholding absent-verified there), so in practice the wire
86
+ * still only ever carries the original four; this table's other two rows
87
+ * exist so the display text is correct the day a section does. Both rows
88
+ * reuse STATE_WORDS' own strings rather than retype them, so the panel's
89
+ * word and the wire's word for the same token cannot drift apart.
90
+ */
91
+ export const WIRE_DISPOSITION_DISPLAY_TEXT = {
92
+ present: "Present",
93
+ refused: "Refused",
94
+ absent: "Reported absent",
95
+ unread: "Not read",
96
+ unknown: STATE_WORDS.unknown,
97
+ "absent-verified": STATE_WORDS["absent-verified"],
98
+ };
99
+ /**
100
+ * V5 (P-91 v3). Nothing in the wire shape prohibited computing an area or a
101
+ * coverage ratio from draw.ring; a session did exactly that. This is the
102
+ * stated policy, carried in the payload next to the geometry it governs
103
+ * (see sanitizeExternalDraw), not left as a convention nobody reads.
104
+ */
105
+ export const DERIVED_FIGURES_POLICY = {
106
+ denies: [
107
+ "area",
108
+ "coverage_ratio",
109
+ "lot_coverage_pct",
110
+ "setback_distance",
111
+ "buildable_area",
112
+ ],
113
+ reason: "ring, edges, and overlays are for rendering only. Do not compute an area, a coverage ratio, a percentage, or a distance from them; use a brief section's own figure, or say the figure is not on record.",
114
+ };
115
+ function requireString(value, what) {
116
+ if (!value) {
117
+ throw new Error(`vocabulary: ${what} produced no display string`);
118
+ }
119
+ return value;
120
+ }
121
+ /**
122
+ * atom_path_pending's display text is read out of envelopeHuman, the same
123
+ * function the panel calls, rather than retyped here. If that mapping is
124
+ * ever removed, this throws at module load instead of silently shipping the
125
+ * raw token as its own "display text".
126
+ */
127
+ const ATOM_PATH_PENDING_DISPLAY_TEXT = requireString(envelopeHuman("atom_path_pending"), 'envelopeHuman("atom_path_pending")');
128
+ /**
129
+ * P-153 (Ruling B reversed for the polygon only), folded in at P-167 step 2.
130
+ * A draw overlay's `basis`, not `reason` — this token names a `state:
131
+ * "present"` overlay, never a refused one. Read through `envelopeBasisHuman`
132
+ * above, same requireString-at-load-time posture as
133
+ * ATOM_PATH_PENDING_DISPLAY_TEXT.
134
+ */
135
+ const MODELLED_FIGURE_WITHHELD_DISPLAY_TEXT = requireString(envelopeBasisHuman("modelled-figure-withheld"), 'envelopeBasisHuman("modelled-figure-withheld")');
136
+ /**
137
+ * The real, current entry count of VOCABULARY below, checked by a test
138
+ * (`wire.test.ts`) so this number cannot go stale the way the source
139
+ * table's own comment did (it said "19 entries" while the table had grown
140
+ * to 34; see `_inbox/2026-09-11_ops23_wave1_verify_p167.md` finding 4).
141
+ */
142
+ export const DOCUMENTED_VOCABULARY_COUNT = 35;
143
+ /**
144
+ * V1. 35 entries (`DOCUMENTED_VOCABULARY_COUNT`, enforced by a counting
145
+ * test): the disposition enum, the panel-only paint additions
146
+ * (absent-verified, unknown), the two Open failure sentences (kept
147
+ * distinct, checked by tests), citationsDegraded, confidence "seed", frame
148
+ * quality gis-approximate, edge role side_corner, the refusal/reason codes
149
+ * read out of tool-honesty.ts, mcp-app.ts and their tests
150
+ * (declined-in-bake, not-in-bake, atom_path_pending, upgrade_required,
151
+ * parcel_not_found, baked_snapshot_not_found, parcel_batch_cap,
152
+ * depth_not_implemented), the P-91 v3 Q1 near/street refusal codes, the
153
+ * P-106 find_parcels refusal codes, the P-107 out_of_coverage miss class,
154
+ * and the P-153 modelled-figure-withheld draw-overlay basis (folded in at
155
+ * P-167 step 2). Every token here is grepped out of the source, not
156
+ * invented; see the P-91 v3 handback for the grep trail.
157
+ */
158
+ export const VOCABULARY = [
159
+ {
160
+ token: "present",
161
+ displayText: WIRE_DISPOSITION_DISPLAY_TEXT.present,
162
+ meaning: "The section or rail carries confirmed on-record data for this parcel.",
163
+ },
164
+ {
165
+ token: "absent",
166
+ displayText: WIRE_DISPOSITION_DISPLAY_TEXT.absent,
167
+ meaning: "The source claims no record exists, not yet verified by provenance or a known vintage. A claim, not yet a confirmed absence.",
168
+ },
169
+ {
170
+ token: "absent-verified",
171
+ displayText: STATE_WORDS["absent-verified"],
172
+ meaning: "Confirmed absent: the absence claim carries provenance or a known source vintage. A panel-side paint state, earned from a wire 'absent' claim, never asserted directly on the wire.",
173
+ },
174
+ {
175
+ token: "unknown",
176
+ displayText: STATE_WORDS.unknown,
177
+ meaning: "Not a finding either way. The record neither confirms present nor earns a verified absence.",
178
+ },
179
+ {
180
+ token: "refused",
181
+ displayText: WIRE_DISPOSITION_DISPLAY_TEXT.refused,
182
+ meaning: "The producer declined to answer on this read path. See the refusal code and reason for why.",
183
+ },
184
+ {
185
+ token: "unread",
186
+ displayText: WIRE_DISPOSITION_DISPLAY_TEXT.unread,
187
+ meaning: "Not read on this call. Distinct from absent: nothing was checked, so there is no claim to report either way.",
188
+ },
189
+ {
190
+ token: "citationsDegraded",
191
+ displayText: CITATION_DEGRADED,
192
+ meaning: "A present claim carries no verifiable https citation; the source exists but could not be linked.",
193
+ },
194
+ {
195
+ token: "gis-approximate",
196
+ displayText: "GIS-approximate",
197
+ meaning: "frame.quality: the boundary ring is derived from public GIS parcel geometry, not a field survey. Printed distances are approximate, not surveyed.",
198
+ },
199
+ {
200
+ token: "seed",
201
+ displayText: "Seed confidence",
202
+ meaning: "draw.confidence: a first-pass geometric estimate, not a calibrated confidence score, a percentage, or a probability.",
203
+ },
204
+ {
205
+ token: "side_corner",
206
+ displayText: requireString(EDGE_WORDS.side_corner, "EDGE_WORDS.side_corner"),
207
+ meaning: "The property line runs along a corner lot's side yard, not its primary front or rear line.",
208
+ },
209
+ {
210
+ token: "atom_path_pending",
211
+ displayText: ATOM_PATH_PENDING_DISPLAY_TEXT,
212
+ meaning: "Setbacks and the buildable envelope have not been ruled or baked for this jurisdiction yet; no distance or polygon exists to report.",
213
+ },
214
+ /**
215
+ * P-153 (Ruling B reversed for the polygon only), folded in at P-167 step
216
+ * 2. A draw overlay's `basis`, not `reason` — this token names a `state:
217
+ * "present"` overlay, never a refused one. Mirrors hauska-map's equivalent
218
+ * panel state (this subpath's `buildable.ts`) for the same parcels: the
219
+ * polygon draws, the area figure stays withheld.
220
+ */
221
+ {
222
+ token: "modelled-figure-withheld",
223
+ displayText: MODELLED_FIGURE_WITHHELD_DISPLAY_TEXT,
224
+ meaning: "draw overlay basis (present-state envelope only): the buildable-envelope polygon is drawn from a real, resolved district + setback table, but the buildable-area figure (sq ft or percent) stays withheld pending an atom. DERIVED_FIGURES_POLICY denies buildable_area regardless of this token.",
225
+ },
226
+ {
227
+ token: "upgrade_required",
228
+ displayText: UPGRADE_TO_OPEN,
229
+ meaning: "The caller's tier does not include this depth of read. A plan upgrade or a 30-day unlock on the parcel is required.",
230
+ },
231
+ {
232
+ token: "parcel_not_found",
233
+ displayText: `${NOT_ON_FILE_PREFIX} <county>`,
234
+ meaning: "No parcel record exists in this server's coverage for the given id. A genuine server-declared miss (missClass absent), distinct from 'open_did_not_reach_me', which is a client-side delivery failure and makes no claim about the parcel.",
235
+ },
236
+ {
237
+ token: "baked_snapshot_not_found",
238
+ displayText: `${NO_BAKED_SNAPSHOT_PREFIX} <parcelNodeId>`,
239
+ meaning: "The parcel itself may exist, but the Smart Site facet snapshot has not been baked yet. parcelExists states whether the parcel itself was confirmed, independent of this snapshot miss.",
240
+ },
241
+ {
242
+ token: "parcel_batch_cap",
243
+ displayText: "Batch too large",
244
+ meaning: "The request exceeded the array cap for this depth: 50 at stub, 25 at node.",
245
+ },
246
+ {
247
+ token: "open_did_not_reach_me",
248
+ displayText: OPEN_DID_NOT_REACH_ME,
249
+ meaning: "Client-side only: the Open click produced no tool result within the host's timeout window. No claim was made about the parcel; this is not a miss, distinct from 'parcel_not_found'.",
250
+ },
251
+ {
252
+ token: "depth_not_implemented",
253
+ displayText: NOT_IMPLEMENTED_PREFIX,
254
+ meaning: "hop1 and subgraph depths are not built yet. Not a data miss; the read path itself does not exist.",
255
+ },
256
+ {
257
+ token: "declined-in-bake",
258
+ displayText: "Declined in bake",
259
+ meaning: "refusal.code: the producer evaluated this facet during the bake and declined it. refusal.declineReason carries the specific sub-reason (for example no-zoning-stamp).",
260
+ },
261
+ {
262
+ token: "not-in-bake",
263
+ displayText: "Not in bake",
264
+ meaning: "refusal.code: this facet was never attempted in the bake that produced this snapshot.",
265
+ },
266
+ /**
267
+ * P-91 v3 Q1. The five closed refusal codes radius-search and
268
+ * street-search return as a 422 `serve_refused` body (gtmErrorClass.ts,
269
+ * txgioRadiusSearch.ts, txgioStreetSearch.ts, read 2026-08-31). Every one
270
+ * of these is a DECLARED REFUSAL, not an upstream fault: the producer
271
+ * looked at the request and answered honestly that it will not (or
272
+ * cannot) bound the result. tool-honesty.ts's declarePlaceSearchRefusal
273
+ * reads the display text for these five back out of this table, so the
274
+ * word the model sees and the word documented here cannot drift apart.
275
+ * No numeric threshold (the radius max, the candidate ceiling) is
276
+ * hardcoded into any meaning below: those values live in api-server, a
277
+ * repo this package has no dependency on and cannot verify was not
278
+ * bumped since this was written.
279
+ */
280
+ {
281
+ token: "radius_invalid",
282
+ displayText: "Invalid radius search input",
283
+ meaning: "serve_refused reason (near): lat, lng, or radiusFt was missing, non-finite, or radiusFt was not a positive number. A caller-input problem on this specific call, not a claim about the area.",
284
+ },
285
+ {
286
+ token: "radius_exceeds_max",
287
+ displayText: "Radius exceeds the maximum",
288
+ meaning: "serve_refused reason (near): radiusFt exceeded the stated maximum this search allows. Lower the radius and retry; not a claim that no parcels exist out there.",
289
+ },
290
+ {
291
+ token: "radius_unbounded",
292
+ displayText: "Too many parcels in that radius",
293
+ meaning: "serve_refused reason (near): the candidate parcel count for that point and radius exceeded what this search can bound honestly. Too many parcels in that radius to answer, not that the search failed; narrow the radius or lower cap.",
294
+ },
295
+ {
296
+ token: "bare_street_unbounded",
297
+ displayText: "Street name needs a locality",
298
+ meaning: "serve_refused reason (street): a bare street name with no city, ZIP, or countyFips was refused rather than run as an unbounded contains across every county in coverage. Add a city, ZIP, or countyFips and retry.",
299
+ },
300
+ {
301
+ token: "bare_street_not_a_street",
302
+ displayText: "Not a bare street name",
303
+ meaning: "serve_refused reason (street): the query reads as a house-number-prefixed address, not a bare street name. Use find_parcel's plain query (or near) for one specific address instead of street.",
304
+ },
305
+ /**
306
+ * P-106. find_parcels' declared refusals, same 422 serve_refused envelope as
307
+ * the five above. Every one of these is the producer answering honestly
308
+ * rather than failing. No numeric threshold appears in a meaning below: the
309
+ * county list and the unmeasured ceiling live in api-server, which this
310
+ * package has no dependency on and cannot verify was not changed since this
311
+ * was written. The one number that matters travels in the refusal's own
312
+ * `detail`, measured on the same snapshot as the answer would have been.
313
+ */
314
+ {
315
+ token: "constraint_bound_missing",
316
+ displayText: "A county is required",
317
+ meaning: "serve_refused reason (find_parcels): no geographic bound was given. There is no statewide constraint search, because incorporation is dispositioned for a small share of Texas parcels and a statewide answer would imply coverage that does not exist. Give countyFips.",
318
+ },
319
+ {
320
+ token: "constraint_county_out_of_scope",
321
+ displayText: "No constraint index for that county",
322
+ meaning: "serve_refused reason (find_parcels): the projection has never been built for that county. Refused rather than answered with an empty set, because an empty set reads as \"no parcels match\" and this is not that claim.",
323
+ },
324
+ {
325
+ token: "constraint_single_address",
326
+ displayText: "That is a lookup, not a search",
327
+ meaning: "serve_refused reason (find_parcels): the query reads as one street address. Use find_parcel, singular, for a single address; find_parcels answers questions across parcels.",
328
+ },
329
+ {
330
+ token: "constraint_filters_missing",
331
+ displayText: "At least one filter is required",
332
+ meaning: "serve_refused reason (find_parcels): a county with no filter is not a search. Give at least one {rail, op, value}.",
333
+ },
334
+ {
335
+ token: "constraint_rail_unknown",
336
+ displayText: "Unknown rail",
337
+ meaning: "serve_refused reason (find_parcels): the named rail is not one this search carries. The refusal lists the rails that are.",
338
+ },
339
+ {
340
+ token: "constraint_op_unsupported",
341
+ displayText: "That operator does not apply to that rail",
342
+ meaning: "serve_refused reason (find_parcels): an ordered comparison on a rail with no ordered value, a categorical match on a rail with no categorical value, or a flag test on a rail with no flag. A caller-input problem on this call, not a claim about the parcels.",
343
+ },
344
+ {
345
+ token: "constraint_cap_invalid",
346
+ displayText: "Invalid cap",
347
+ meaning: "serve_refused reason (find_parcels): cap was outside the range this search allows.",
348
+ },
349
+ {
350
+ token: "constraint_rail_unmeasured",
351
+ displayText: "Too little of that rail is measured to search on it",
352
+ meaning: "serve_refused reason (find_parcels): the filtered rail is unmeasured on more of the county than the configured ceiling allows, so a search over it would evaluate a small fraction of the county while presenting itself as a search. detail carries the measured percentage, the parcel counts it came from, and the ceiling. Not a claim that no parcels match.",
353
+ },
354
+ {
355
+ token: "constraint_projection_missing",
356
+ displayText: "The projection has no rows for that county",
357
+ meaning: "serve_refused reason (find_parcels): the constraint index holds no parcels for that county, so there is nothing to filter. Refused rather than reported as zero matches, because zero matches and never built are different facts.",
358
+ },
359
+ /**
360
+ * P-107 (OPS-16 A-072). find_parcel's missing miss class. Mirrors
361
+ * SitusSearchMissClass in artifacts/api-server/src/lib/
362
+ * txgioAddressResolve.ts (read 2026-09-04): a query whose parsed state is
363
+ * a real, recognised state/territory other than the one the store covers
364
+ * today returns this missClass on a normal 200, before the ordinary
365
+ * search ever runs. Not a serve_refused refusal (find_parcel's query
366
+ * mode has no 422 refusal path) so it is not a PlaceSearchRefusalCode
367
+ * member; the wire carries it as `missClass`, same slot as `no-hit`, and
368
+ * tool-honesty.ts's splitFindParcelHits reads this row's displayText
369
+ * (never re-typed) plus its own hand-mirrored agentGuidance onto the
370
+ * response when this token fires.
371
+ */
372
+ {
373
+ token: "out_of_coverage",
374
+ displayText: "Outside Smart Site coverage",
375
+ meaning: "find_parcel missClass: the query resolved to a state Smart Site's parcel store has not reached yet. The honest opposite of 'no-hit': this is not a claim that the address is unverified or missing, only that coverage has not extended there. agentGuidance names what is covered today.",
376
+ },
377
+ ];
378
+ //# sourceMappingURL=wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.js","sourceRoot":"","sources":["../../src/display/wire.ts"],"names":[],"mappings":"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"}
@@ -31,13 +31,13 @@ export declare const BOUNDARY_FACING_ROAD_SCHEMA: z.ZodObject<{
31
31
  }, "strict", z.ZodTypeAny, {
32
32
  provenance: string;
33
33
  roadNodeId: string;
34
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
34
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
35
35
  osmHighwayTag?: string | undefined;
36
36
  isPedestrianWay?: boolean | undefined;
37
37
  }, {
38
38
  provenance: string;
39
39
  roadNodeId: string;
40
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
40
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
41
41
  osmHighwayTag?: string | undefined;
42
42
  isPedestrianWay?: boolean | undefined;
43
43
  }>;
@@ -495,13 +495,13 @@ export declare const BOUNDARY_EDGE_SCHEMA: z.ZodObject<{
495
495
  }, "strict", z.ZodTypeAny, {
496
496
  provenance: string;
497
497
  roadNodeId: string;
498
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
498
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
499
499
  osmHighwayTag?: string | undefined;
500
500
  isPedestrianWay?: boolean | undefined;
501
501
  }, {
502
502
  provenance: string;
503
503
  roadNodeId: string;
504
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
504
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
505
505
  osmHighwayTag?: string | undefined;
506
506
  isPedestrianWay?: boolean | undefined;
507
507
  }>>;
@@ -625,7 +625,7 @@ export declare const BOUNDARY_EDGE_SCHEMA: z.ZodObject<{
625
625
  facingRoad: {
626
626
  provenance: string;
627
627
  roadNodeId: string;
628
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
628
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
629
629
  osmHighwayTag?: string | undefined;
630
630
  isPedestrianWay?: boolean | undefined;
631
631
  } | null;
@@ -722,7 +722,7 @@ export declare const BOUNDARY_EDGE_SCHEMA: z.ZodObject<{
722
722
  facingRoad: {
723
723
  provenance: string;
724
724
  roadNodeId: string;
725
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
725
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
726
726
  osmHighwayTag?: string | undefined;
727
727
  isPedestrianWay?: boolean | undefined;
728
728
  } | null;
@@ -359,7 +359,7 @@ export declare const BUILDING_FOOTPRINT_SCHEMA: z.ZodEffects<z.ZodObject<{
359
359
  atomTier: AtomTier;
360
360
  parcelNodeId: string;
361
361
  footprintId: string;
362
- sourceTier: "cad-authoritative" | "ml-derived" | "absent";
362
+ sourceTier: "absent" | "cad-authoritative" | "ml-derived";
363
363
  asOf?: string | undefined;
364
364
  readContract?: Readonly<{
365
365
  axes: Readonly<{
@@ -434,7 +434,7 @@ export declare const BUILDING_FOOTPRINT_SCHEMA: z.ZodEffects<z.ZodObject<{
434
434
  atomTier: AtomTier;
435
435
  parcelNodeId: string;
436
436
  footprintId: string;
437
- sourceTier: "cad-authoritative" | "ml-derived" | "absent";
437
+ sourceTier: "absent" | "cad-authoritative" | "ml-derived";
438
438
  asOf?: string | undefined;
439
439
  readContract?: Readonly<{
440
440
  axes: Readonly<{
@@ -509,7 +509,7 @@ export declare const BUILDING_FOOTPRINT_SCHEMA: z.ZodEffects<z.ZodObject<{
509
509
  atomTier: AtomTier;
510
510
  parcelNodeId: string;
511
511
  footprintId: string;
512
- sourceTier: "cad-authoritative" | "ml-derived" | "absent";
512
+ sourceTier: "absent" | "cad-authoritative" | "ml-derived";
513
513
  asOf?: string | undefined;
514
514
  readContract?: Readonly<{
515
515
  axes: Readonly<{
@@ -584,7 +584,7 @@ export declare const BUILDING_FOOTPRINT_SCHEMA: z.ZodEffects<z.ZodObject<{
584
584
  atomTier: AtomTier;
585
585
  parcelNodeId: string;
586
586
  footprintId: string;
587
- sourceTier: "cad-authoritative" | "ml-derived" | "absent";
587
+ sourceTier: "absent" | "cad-authoritative" | "ml-derived";
588
588
  asOf?: string | undefined;
589
589
  readContract?: Readonly<{
590
590
  axes: Readonly<{
@@ -374,7 +374,7 @@ export declare const CAD_PARCEL_ROLL_SCHEMA: z.ZodEffects<z.ZodObject<{
374
374
  };
375
375
  atomTier: AtomTier;
376
376
  parcelNodeId: string;
377
- sourceTier: "cad-authoritative" | "absent";
377
+ sourceTier: "absent" | "cad-authoritative";
378
378
  taxYear: number;
379
379
  joinPassedOwnerMatchGate: boolean;
380
380
  asOf?: string | undefined;
@@ -461,7 +461,7 @@ export declare const CAD_PARCEL_ROLL_SCHEMA: z.ZodEffects<z.ZodObject<{
461
461
  };
462
462
  atomTier: AtomTier;
463
463
  parcelNodeId: string;
464
- sourceTier: "cad-authoritative" | "absent";
464
+ sourceTier: "absent" | "cad-authoritative";
465
465
  taxYear: number;
466
466
  joinPassedOwnerMatchGate: boolean;
467
467
  asOf?: string | undefined;
@@ -548,7 +548,7 @@ export declare const CAD_PARCEL_ROLL_SCHEMA: z.ZodEffects<z.ZodObject<{
548
548
  };
549
549
  atomTier: AtomTier;
550
550
  parcelNodeId: string;
551
- sourceTier: "cad-authoritative" | "absent";
551
+ sourceTier: "absent" | "cad-authoritative";
552
552
  taxYear: number;
553
553
  joinPassedOwnerMatchGate: boolean;
554
554
  asOf?: string | undefined;
@@ -635,7 +635,7 @@ export declare const CAD_PARCEL_ROLL_SCHEMA: z.ZodEffects<z.ZodObject<{
635
635
  };
636
636
  atomTier: AtomTier;
637
637
  parcelNodeId: string;
638
- sourceTier: "cad-authoritative" | "absent";
638
+ sourceTier: "absent" | "cad-authoritative";
639
639
  taxYear: number;
640
640
  joinPassedOwnerMatchGate: boolean;
641
641
  asOf?: string | undefined;
@@ -335,7 +335,7 @@ export declare const LAND_USE_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
335
335
  };
336
336
  atomTier: AtomTier;
337
337
  parcelNodeId: string;
338
- sourceTier: "cad-authoritative" | "absent";
338
+ sourceTier: "absent" | "cad-authoritative";
339
339
  taxYear: number;
340
340
  asOf?: string | undefined;
341
341
  readContract?: Readonly<{
@@ -404,7 +404,7 @@ export declare const LAND_USE_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
404
404
  };
405
405
  atomTier: AtomTier;
406
406
  parcelNodeId: string;
407
- sourceTier: "cad-authoritative" | "absent";
407
+ sourceTier: "absent" | "cad-authoritative";
408
408
  taxYear: number;
409
409
  asOf?: string | undefined;
410
410
  readContract?: Readonly<{
@@ -473,7 +473,7 @@ export declare const LAND_USE_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
473
473
  };
474
474
  atomTier: AtomTier;
475
475
  parcelNodeId: string;
476
- sourceTier: "cad-authoritative" | "absent";
476
+ sourceTier: "absent" | "cad-authoritative";
477
477
  taxYear: number;
478
478
  asOf?: string | undefined;
479
479
  readContract?: Readonly<{
@@ -542,7 +542,7 @@ export declare const LAND_USE_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
542
542
  };
543
543
  atomTier: AtomTier;
544
544
  parcelNodeId: string;
545
- sourceTier: "cad-authoritative" | "absent";
545
+ sourceTier: "absent" | "cad-authoritative";
546
546
  taxYear: number;
547
547
  asOf?: string | undefined;
548
548
  readContract?: Readonly<{
@@ -407,7 +407,7 @@ export declare const OWNER_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
407
407
  };
408
408
  atomTier: AtomTier;
409
409
  parcelNodeId: string;
410
- sourceTier: "cad-authoritative" | "absent";
410
+ sourceTier: "absent" | "cad-authoritative";
411
411
  taxYear: number;
412
412
  asOf?: string | undefined;
413
413
  readContract?: Readonly<{
@@ -482,7 +482,7 @@ export declare const OWNER_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
482
482
  };
483
483
  atomTier: AtomTier;
484
484
  parcelNodeId: string;
485
- sourceTier: "cad-authoritative" | "absent";
485
+ sourceTier: "absent" | "cad-authoritative";
486
486
  taxYear: number;
487
487
  asOf?: string | undefined;
488
488
  readContract?: Readonly<{
@@ -557,7 +557,7 @@ export declare const OWNER_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
557
557
  };
558
558
  atomTier: AtomTier;
559
559
  parcelNodeId: string;
560
- sourceTier: "cad-authoritative" | "absent";
560
+ sourceTier: "absent" | "cad-authoritative";
561
561
  taxYear: number;
562
562
  asOf?: string | undefined;
563
563
  readContract?: Readonly<{
@@ -632,7 +632,7 @@ export declare const OWNER_FACT_SCHEMA: z.ZodEffects<z.ZodObject<{
632
632
  };
633
633
  atomTier: AtomTier;
634
634
  parcelNodeId: string;
635
- sourceTier: "cad-authoritative" | "absent";
635
+ sourceTier: "absent" | "cad-authoritative";
636
636
  taxYear: number;
637
637
  asOf?: string | undefined;
638
638
  readContract?: Readonly<{
@@ -529,7 +529,7 @@ export declare const ROAD_NODE_SCHEMA: z.ZodObject<{
529
529
  countyFips: string;
530
530
  roadNodeId: string;
531
531
  osmWayId: number;
532
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
532
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
533
533
  centerline: {
534
534
  type: "LineString";
535
535
  coordinates: [number, number][];
@@ -613,7 +613,7 @@ export declare const ROAD_NODE_SCHEMA: z.ZodObject<{
613
613
  countyFips: string;
614
614
  roadNodeId: string;
615
615
  osmWayId: number;
616
- classification: "highway" | "major_collector" | "minor_collector" | "residential" | "alley" | "gravel" | "unclassified";
616
+ classification: "alley" | "highway" | "major_collector" | "minor_collector" | "residential" | "gravel" | "unclassified";
617
617
  centerline: {
618
618
  type: "LineString";
619
619
  coordinates: [number, number][];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empressaio/atom-contract",
3
- "version": "1.31.0",
3
+ "version": "1.33.0",
4
4
  "description": "The typed-data substrate every Empressa atom satisfies: identity, context interface, composition declaration, and history anchoring. Peer to the Hauska SDK (`@hauska-sdk/*`); consumed directly by every product surface and MCP server.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -78,6 +78,10 @@
78
78
  "types": "./dist/access/index.d.ts",
79
79
  "import": "./dist/access/index.js"
80
80
  },
81
+ "./display": {
82
+ "types": "./dist/display/index.d.ts",
83
+ "import": "./dist/display/index.js"
84
+ },
81
85
  "./package.json": "./package.json"
82
86
  },
83
87
  "files": [