@mailwoman/kind-classifier 9.2.0 → 9.3.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/README.md CHANGED
@@ -46,7 +46,7 @@ scoreVague(shape: QueryShapeLike): number
46
46
  ## Pipeline position
47
47
 
48
48
  ```
49
- locale-gate → kind-classifier → phrase-grouper → classifier → ...
49
+ locale-hint → kind-classifier → phrase-grouper → classifier → ...
50
50
  ```
51
51
 
52
52
  ## Design
@@ -59,7 +59,7 @@ locale-gate → kind-classifier → phrase-grouper → classifier → ...
59
59
  ## Related
60
60
 
61
61
  - [`@mailwoman/query-shape`](../query-shape) — feeds structural data into this stage
62
- - [`@mailwoman/locale-gate`](../locale-gate) — feeds locale context
62
+ - [`@mailwoman/locale-hint`](../locale-hint) — feeds locale context
63
63
  - [`@mailwoman/phrase-grouper`](../phrase-grouper) — Stage 2.7, next in the pipeline
64
64
  - [Staged Pipeline Contract](https://github.com/sister-software/mailwoman/blob/main/docs/engineering/reference/STAGES.mdx)
65
65
 
@@ -16,9 +16,9 @@
16
16
  * inform the markers without moving the routing decision.
17
17
  */
18
18
 
19
- import { deriveIntentMarkers } from "./intent-markers.ts"
20
- import { scoreBareToponym, scoreNearMe, scoreRoutePair } from "./intent-rules.ts"
21
- import { createScorePOICategory, createScorePOIQuery, type POIPhraseLookup } from "./poi.ts"
19
+ import { deriveIntentMarkers } from "#intent-markers"
20
+ import { scoreBareToponym, scoreNearMe, scoreRoutePair } from "#intent-rules"
21
+ import { createScorePOICategory, createScorePOIQuery, type POIPhraseLookup } from "#poi"
22
22
  import {
23
23
  scoreIntersection,
24
24
  scoreLandmark,
@@ -28,7 +28,7 @@ import {
28
28
  scoreStructuredAddress,
29
29
  scoreVague,
30
30
  scoreVenueLandmark,
31
- } from "./rules.ts"
31
+ } from "#rules"
32
32
  import type {
33
33
  LocaleHint,
34
34
  NormalizedInputLite,
@@ -36,7 +36,7 @@ import type {
36
36
  QueryKind,
37
37
  QueryKindResult,
38
38
  QueryShapeLike,
39
- } from "./types.ts"
39
+ } from "#types"
40
40
 
41
41
  interface KindScorer {
42
42
  kind: QueryKind
@@ -13,13 +13,13 @@
13
13
  * See `docs/engineering/reference/STAGES.md` § Stage 2.5 for the contract.
14
14
  */
15
15
 
16
- export { classifyKind, classifyKindSync, createKindClassifier } from "./classify.ts"
17
- export type { KindClassifierOpts } from "./classify.ts"
18
- export { deriveIntentMarkers } from "./intent-markers.ts"
19
- export type { IntentMarkerContext } from "./intent-markers.ts"
20
- export { nearMeSubject, scoreBareToponym, scoreNearMe, scoreRoutePair } from "./intent-rules.ts"
21
- export { matchPOICategory, matchPOISubject } from "./poi.ts"
22
- export type { POIPhraseMatch, POIPhraseLookup, POIQuerySpan, POISpatialRelation, POISubjectMatch } from "./poi.ts"
16
+ export { classifyKind, classifyKindSync, createKindClassifier } from "#classify"
17
+ export type { KindClassifierOpts } from "#classify"
18
+ export { deriveIntentMarkers } from "#intent-markers"
19
+ export type { IntentMarkerContext } from "#intent-markers"
20
+ export { nearMeSubject, scoreBareToponym, scoreNearMe, scoreRoutePair } from "#intent-rules"
21
+ export { matchPOICategory, matchPOISubject } from "#poi"
22
+ export type { POIPhraseMatch, POIPhraseLookup, POIQuerySpan, POISpatialRelation, POISubjectMatch } from "#poi"
23
23
 
24
24
  export {
25
25
  scoreIntersection,
@@ -30,9 +30,9 @@ export {
30
30
  scoreStructuredAddress,
31
31
  scoreVague,
32
32
  scoreVenueLandmark,
33
- } from "./rules.ts"
33
+ } from "#rules"
34
34
 
35
- export { QueryIntentCode } from "./types.ts"
35
+ export { QueryIntentCode } from "#types"
36
36
 
37
37
  export type {
38
38
  LocaleHint,
@@ -41,4 +41,4 @@ export type {
41
41
  QueryKind,
42
42
  QueryKindResult,
43
43
  QueryShapeLike,
44
- } from "./types.ts"
44
+ } from "#types"
@@ -9,15 +9,15 @@
9
9
  * Three of the four intent kinds can raise their marker here, from the string alone. The fourth —
10
10
  * `bare_toponym`'s `declared_ambiguity` — cannot: its trigger is the dominance margin of the
11
11
  * RESOLVED candidate list, which does not exist yet at Stage 2.5. That one is raised by
12
- * `mailwoman/query-intent.ts` after the resolve, against the measured 0.5-log10 cut. The split is
12
+ * `mailwoman/query-intent.ts` after the resolve, against the measured 0.5-log10 threshold. The split is
13
13
  * deliberate and it is why this module never emits `declared_ambiguity`: a marker that asserted
14
14
  * ambiguity from the string alone would be declaring that every bare city name is ambiguous, which
15
15
  * is false 89.1% of the time (the measured table behind `DECISIVE_MARGIN_LOG10`).
16
16
  */
17
17
 
18
- import { nearMeSubject } from "./intent-rules.ts"
19
- import { matchPOICategory, type POIPhraseLookup } from "./poi.ts"
20
- import type { NormalizedInputLite, QueryIntentMarker, QueryKind } from "./types.ts"
18
+ import { nearMeSubject } from "#intent-rules"
19
+ import { matchPOICategory, type POIPhraseLookup } from "#poi"
20
+ import type { NormalizedInputLite, QueryIntentMarker, QueryKind } from "#types"
21
21
 
22
22
  /**
23
23
  * Context the marker builder needs beyond the scored kinds.
@@ -50,6 +50,8 @@ export function deriveIntentMarkers(
50
50
  const markers: QueryIntentMarker[] = []
51
51
 
52
52
  if (fired.has("route_pair")) {
53
+ // Whitespace-only split, not `wordsOf`: `route_pair` inputs are comma-free by construction (a comma
54
+ // disqualifies the kind), and the tokens are re-joined verbatim into the message.
53
55
  const tokens = ctx.input.normalized.trim().split(/\s+/)
54
56
 
55
57
  markers.push({
@@ -79,9 +81,9 @@ export function deriveIntentMarkers(
79
81
  evidence: {
80
82
  subject,
81
83
  /**
82
- * The SEAM, named but not wired (ROAD_TO_V9 §4.4 scopes v9 to classification). Photon's `/api` already accepts
83
- * `lat`/`lon` location-bias params — `photon/` is the eventual consumer of this marker, and this string is the
84
- * note that says where it plugs in.
84
+ * THE PLUG POINT, named but not wired (ROAD_TO_V9 §4.4 scopes v9 to classification). Photon's `/api` already
85
+ * accepts `lat`/`lon` location-bias params — `photon/` is the eventual consumer of this marker, and this string
86
+ * is the note that says where it plugs in.
85
87
  */
86
88
  focusParameter: "photon:lat/lon",
87
89
  },
@@ -23,8 +23,8 @@
23
23
  * ending "near me" is not a locality and answering it as one is the bug.
24
24
  */
25
25
 
26
- import { MAX_LOCALITY_ONLY_LENGTH, STREET_SUFFIXES } from "./rules.ts"
27
- import type { NormalizedInputLite, QueryShapeLike } from "./types.ts"
26
+ import { isDisqualifyingStreetSuffix, MAX_LOCALITY_ONLY_LENGTH, wordsOf } from "#rules"
27
+ import type { NormalizedInputLite, QueryShapeLike } from "#types"
28
28
 
29
29
  /**
30
30
  * `locality_only` scores 0.85. Both refinement kinds sit under it by a whole confidence step so no float-comparison
@@ -186,13 +186,6 @@ const DEICTIC_LOCATOR_TAIL =
186
186
  const DEICTIC_ADVERB_TAIL =
187
187
  /\b(?:nearby|near\s?by|close\s+by|around\s+here|in\s+my\s+(?:area|neighborhood|neighbourhood))\s*$/
188
188
 
189
- /**
190
- * Split on whitespace + commas, the way the other rules in this package do.
191
- */
192
- function wordsOf(text: string): string[] {
193
- return text.split(/[\s,]+/).filter(Boolean)
194
- }
195
-
196
189
  /**
197
190
  * True when the input carries a deictic locator tail in EITHER form.
198
191
  */
@@ -201,12 +194,12 @@ function hasDeicticTail(lowercased: string): boolean {
201
194
  }
202
195
 
203
196
  /**
204
- * The gates `bare_toponym` and `route_pair` share: no address grammar of any kind, one segment, alpha throughout.
197
+ * The conditions `bare_toponym` and `route_pair` share: no address grammar of any kind, one segment, alpha throughout.
205
198
  *
206
199
  * Returns the word list when the input clears them, `null` when it does not. Deliberately a SUPERSET of
207
- * `scoreLocalityOnly`'s gates (which admits two segments), so `bare_toponym` is a strict refinement of `locality_only`
208
- * and can never fire where `locality_only` did not — the property `intent-rules.test.ts` asserts and the reason the
209
- * ranking discipline above is enough to keep the top kind pinned.
200
+ * `scoreLocalityOnly`'s conditions (which admit two segments), so `bare_toponym` is a strict refinement of
201
+ * `locality_only` and can never fire where `locality_only` did not — the property `intent-rules.test.ts` asserts and
202
+ * the reason the ranking discipline above is enough to keep the top kind pinned.
210
203
  */
211
204
  function bareNameWords(input: NormalizedInputLite, shape: QueryShapeLike): string[] | null {
212
205
  const text = input.normalized.trim()
@@ -232,7 +225,7 @@ function bareNameWords(input: NormalizedInputLite, shape: QueryShapeLike): strin
232
225
  if (!words.length || words.length > MAX_BARE_TOPONYM_WORDS) return null
233
226
 
234
227
  for (const word of words) {
235
- if (STREET_SUFFIXES.has(word.toLowerCase())) return null
228
+ if (isDisqualifyingStreetSuffix(word)) return null
236
229
  }
237
230
 
238
231
  return words
@@ -9,7 +9,7 @@
9
9
  * `poiQueryKind` flag (default-ON since 2026-07-20). Spec §3.1.
10
10
  */
11
11
 
12
- import type { NormalizedInputLite, QueryShapeLike } from "./types.ts"
12
+ import type { NormalizedInputLite, QueryShapeLike } from "#types"
13
13
 
14
14
  /**
15
15
  * Comma-segment ceiling for a POI-led query. Past it the input is a venue plus a full address (`X, 350 5th Ave, New
@@ -40,6 +40,31 @@ export interface POIPhraseMatch {
40
40
  * Wikidata QID, when known. `kind: "brand"` only — absent when a brand resolved by name alone (no QID match).
41
41
  */
42
42
  wikidata?: string
43
+ /**
44
+ * Whether this hit is one member of a set the caller must search TOGETHER, rather than one candidate in a preference
45
+ * list.
46
+ *
47
+ * A lookup returning several hits means two different things, and the difference decides whether narrowing to the
48
+ * first is an answer or an invented ordering. A phrase index returns the categories one typed phrase could name, the
49
+ * curated reading first (`credit union` → the `bank` rollup its synonym redirects to, then the standalone
50
+ * `credit_union` category), and the first entry IS the subject. An affordance rung returns every entity kind that
51
+ * affords ONE activity, in a stable enumeration that is not a preference, and taking the first picks a winner nobody
52
+ * authored.
53
+ *
54
+ * Set on every member of such a set. {@link matchPOISubject} then carries them all, the POI branch searches their
55
+ * union, and the candidate ordering the resolver already owns decides the answer. Absent — the committed lexicon's
56
+ * shape — keeps the first-hit reading unchanged.
57
+ */
58
+ searchAsSet?: boolean
59
+ /**
60
+ * ISO 3166-1 alpha-2 countries the authority behind this hit scopes its claim to. Absent = the claim holds
61
+ * everywhere.
62
+ *
63
+ * A scope is a statement about ESTABLISHMENTS, so it is judged against the country of the place being searched, not
64
+ * the caller's locale: the locale is the lens the phrase is read through, and it says nothing about where the claim
65
+ * holds. `matchPOISubject` carries the value untouched; the POI intent stage binds it once the anchor has resolved.
66
+ */
67
+ countryScope?: readonly string[]
43
68
  }
44
69
 
45
70
  /**
@@ -62,7 +87,19 @@ export interface POIQuerySpan {
62
87
  * Which lexicon this hit came from. Existing category lookups set `"category"` (backward-compatible default).
63
88
  */
64
89
  export interface POISubjectMatch {
90
+ /**
91
+ * The hit the subject SCORES under — its kind and its confidence. Always `matches[0]`; the two are built together in
92
+ * one place so they cannot disagree.
93
+ */
65
94
  match: POIPhraseMatch
95
+ /**
96
+ * Every category the subject reaches, `match` first.
97
+ *
98
+ * One entry unless the lookup returned a {@link POIPhraseMatch.searchAsSet} set, in which case it holds the whole set
99
+ * and the POI branch searches their union. The order is the order the lookup returned and states no preference:
100
+ * nothing downstream may read position as rank.
101
+ */
102
+ matches: POIPhraseMatch[]
66
103
  /**
67
104
  * The matched subject text as it appeared in the query.
68
105
  */
@@ -105,11 +142,26 @@ const ANCHOR_SEPARATOR = /,\s*|\s(near|in|at|around|to)\s+/gi
105
142
  */
106
143
  const MAX_SUBJECT_TOKENS = 8
107
144
 
145
+ /**
146
+ * The categories one candidate subject reaches, from the hits the lookup returned for it.
147
+ *
148
+ * The whole array when the first hit declares {@link POIPhraseMatch.searchAsSet} — carried as the lookup returned it,
149
+ * never filtered, so a rung that flagged only some of its members loses nothing here and the inconsistency stays
150
+ * visible to whoever reads the set. Otherwise the first hit alone, which is the preference-list reading the committed
151
+ * phrase index has always had.
152
+ */
153
+ function reachedMatches(hits: ReadonlyArray<POIPhraseMatch>): POIPhraseMatch[] {
154
+ return hits[0]!.searchAsSet ? [...hits] : [hits[0]!]
155
+ }
156
+
108
157
  /**
109
158
  * Match a POI subject: the whole input, or the text before the FIRST anchor separator WHOSE PREFIX HITS THE LEXICON (≤
110
159
  * 8 tokens). Scans separator occurrences left-to-right — a lexicon phrase may itself contain a bare separator word
111
160
  * (e.g. "walk in clinic"), so the first separator isn't necessarily the right split point. Returns null when the
112
161
  * lexicon never fires — including comma-ridden full addresses whose leading segment isn't a lexicon phrase.
162
+ *
163
+ * The winning candidate's hits are carried per {@link reachedMatches}: the first hit, or the whole set when the lookup
164
+ * declared one.
113
165
  */
114
166
  export function matchPOISubject(
115
167
  text: string,
@@ -124,8 +176,11 @@ export function matchPOISubject(
124
176
  const whole = lookup(trimmed, locale)
125
177
 
126
178
  if (whole.length) {
179
+ const matches = reachedMatches(whole)
180
+
127
181
  return {
128
- match: whole[0]!,
182
+ match: matches[0]!,
183
+ matches,
129
184
  subject: trimmed,
130
185
  subjectSpan: { text: trimmed, start: inputStart, end: inputStart + trimmed.length },
131
186
  remainder: "",
@@ -137,7 +192,8 @@ export function matchPOISubject(
137
192
 
138
193
  const subject = trimmed.slice(0, separator.index).trim()
139
194
 
140
- // Subjects only grow as the scan moves right — once over budget, later splits are too.
195
+ // Subjects only grow as the scan moves right — once over budget, later splits are too. Whitespace-only
196
+ // split, not `wordsOf`: a comma inside a subject is real content here, not a separator to erase.
141
197
  if (subject.split(/\s+/).length > MAX_SUBJECT_TOKENS) break
142
198
 
143
199
  const hits = lookup(subject, locale)
@@ -152,9 +208,11 @@ export function matchPOISubject(
152
208
  const anchorOffset = trimmed.indexOf(remainder, separator.index + separator[0].length)
153
209
  const relationText = separator[1] ?? ","
154
210
  const relationOffset = separator[1] ? separator.index + separator[0].indexOf(separator[1]) : separator.index
211
+ const matches = reachedMatches(hits)
155
212
 
156
213
  return {
157
- match: hits[0]!,
214
+ match: matches[0]!,
215
+ matches,
158
216
  subject,
159
217
  subjectSpan: {
160
218
  text: subject,
@@ -241,7 +299,7 @@ export function createScorePOICategory(
241
299
 
242
300
  /**
243
301
  * The whole-input category hit behind a `poi_category` verdict, for the marker's evidence. `null` when the input is not
244
- * a bare category — same gates as {@link createScorePOICategory}, so the two cannot disagree.
302
+ * a bare category — same conditions as {@link createScorePOICategory}, so the two cannot disagree.
245
303
  */
246
304
  export function matchPOICategory(
247
305
  text: string,
@@ -10,7 +10,9 @@
10
10
  * regex set per new locale, not 50K dictionary entries.
11
11
  */
12
12
 
13
- import type { NormalizedInputLite, QueryShapeLike } from "./types.ts"
13
+ import { NAME_PRONE_US_SUFFIXES, US_STREET_SUFFIX_LOOKUP } from "@mailwoman/codex/us/street-suffix"
14
+
15
+ import type { NormalizedInputLite, QueryShapeLike } from "#types"
14
16
 
15
17
  /**
16
18
  * Longest input still plausible as a bare venue or landmark name. Beyond it the query is carrying an address as well,
@@ -128,34 +130,25 @@ export function scoreLandmark(input: NormalizedInputLite, _shape: QueryShapeLike
128
130
  }
129
131
 
130
132
  /**
131
- * Street-suffix tokens that indicate an address, not a venue name. Shared with `intent-rules.ts` the intent kinds
132
- * disqualify on the same vocabulary, and a second copy would drift.
133
+ * Split on whitespace + commas and drop empty words the word grammar shared with `intent-rules.ts`. Dropping empties
134
+ * matters: a trailing comma or doubled separator otherwise yields an empty string that inflates the word count and
135
+ * falsifies every-word predicates like the proper-case check below.
133
136
  */
134
- export const STREET_SUFFIXES: ReadonlySet<string> = new Set([
135
- "st",
136
- "street",
137
- "ave",
138
- "avenue",
139
- "blvd",
140
- "boulevard",
141
- "rd",
142
- "road",
143
- "dr",
144
- "drive",
145
- "ln",
146
- "lane",
147
- "ct",
148
- "court",
149
- "pl",
150
- "place",
151
- "way",
152
- "pkwy",
153
- "parkway",
154
- "hwy",
155
- "highway",
156
- "cir",
157
- "circle",
158
- ])
137
+ export function wordsOf(text: string): string[] {
138
+ return text.split(/[\s,]+/).filter((word) => word.length > 0)
139
+ }
140
+
141
+ /**
142
+ * True when a word is USPS street-suffix vocabulary that unambiguously signals an address — the full Pub-28 table via
143
+ * `@mailwoman/codex`, minus its curated name-prone canonicals (PARK, FIELD, HILL, LAKE, …). Those double as ordinary
144
+ * proper-name heads ("Wrigley Field", "Menlo Park"), and disqualifying on them would reject the very venue and place
145
+ * names the rules below exist to capture. Shared with `intent-rules.ts` so both rule sets read one definition.
146
+ */
147
+ export function isDisqualifyingStreetSuffix(word: string): boolean {
148
+ const canonical = US_STREET_SUFFIX_LOOKUP.get(word.trim().toLowerCase())
149
+
150
+ return canonical !== undefined && !NAME_PRONE_US_SUFFIXES.has(canonical)
151
+ }
159
152
 
160
153
  /**
161
154
  * `landmark` rule (venue/named-place variant): short capitalized input with no street suffixes, no postcode hits, and
@@ -181,11 +174,11 @@ export function scoreVenueLandmark(input: NormalizedInputLite, shape: QueryShape
181
174
 
182
175
  if (segCount > 2) return 0
183
176
 
184
- // Reject if any word is a street suffix.
185
- const words = text.split(/[\s,]+/)
177
+ // Reject if any word is an unambiguous street suffix.
178
+ const words = wordsOf(text)
186
179
 
187
180
  for (const w of words) {
188
- if (STREET_SUFFIXES.has(w.toLowerCase())) return 0
181
+ if (isDisqualifyingStreetSuffix(w)) return 0
189
182
  }
190
183
 
191
184
  // Reject if the first token is a pure number (house-number-leading pattern).
package/lib/types.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ /**
8
+ * Re-exports of the canonical types from `@mailwoman/core/pipeline`.
9
+ */
10
+ export type { LocaleHint, QueryIntentMarker, QueryKind, QueryKindResult } from "@mailwoman/core/pipeline"
11
+ export { QueryIntentCode } from "@mailwoman/core/pipeline"
12
+
13
+ /**
14
+ * The minimal input shapes consumed by `classifyKind` come from `@mailwoman/query-shape` — one declaration shared by
15
+ * every Stage-2.x consumer. `QueryShapeLike` stays this package's public name for its narrow read-only view.
16
+ */
17
+ export type { NormalizedInputLite, QueryShapeSegmentsView as QueryShapeLike } from "@mailwoman/query-shape"
package/out/classify.d.ts CHANGED
@@ -15,8 +15,8 @@
15
15
  * are scored below their structural incumbent precisely so they land in `alternatives`, where they
16
16
  * inform the markers without moving the routing decision.
17
17
  */
18
- import { type POIPhraseLookup } from "./poi.ts";
19
- import type { LocaleHint, NormalizedInputLite, QueryKindResult, QueryShapeLike } from "./types.ts";
18
+ import { type POIPhraseLookup } from "#poi";
19
+ import type { LocaleHint, NormalizedInputLite, QueryKindResult, QueryShapeLike } from "#types";
20
20
  /**
21
21
  * Classify the query shape into a `QueryKind`. Synchronous + pure — produces the same result for the same `(input,
22
22
  * shape)` pair.
@@ -1 +1 @@
1
- {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAA+C,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAW5F,OAAO,KAAK,EACX,UAAU,EACV,mBAAmB,EAGnB,eAAe,EACf,cAAc,EACd,MAAM,YAAY,CAAA;AAkEnB;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,eAAe,CAMnG;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CACjC,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,cAAc,EACrB,OAAO,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,GAAE,kBAAuB,GAC3B,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,eAAe,CAAC,CA+BtG"}
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../lib/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAA+C,KAAK,eAAe,EAAE,MAAM,MAAM,CAAA;AAWxF,OAAO,KAAK,EACX,UAAU,EACV,mBAAmB,EAGnB,eAAe,EACf,cAAc,EACd,MAAM,QAAQ,CAAA;AAkEf;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,eAAe,CAMnG;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CACjC,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,cAAc,EACrB,OAAO,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,GAAE,kBAAuB,GAC3B,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,eAAe,CAAC,CA+BtG"}
package/out/classify.js CHANGED
@@ -15,10 +15,10 @@
15
15
  * are scored below their structural incumbent precisely so they land in `alternatives`, where they
16
16
  * inform the markers without moving the routing decision.
17
17
  */
18
- import { deriveIntentMarkers } from "./intent-markers.js";
19
- import { scoreBareToponym, scoreNearMe, scoreRoutePair } from "./intent-rules.js";
20
- import { createScorePOICategory, createScorePOIQuery } from "./poi.js";
21
- import { scoreIntersection, scoreLandmark, scoreLocalityOnly, scorePoBox, scorePostcodeOnly, scoreStructuredAddress, scoreVague, scoreVenueLandmark, } from "./rules.js";
18
+ import { deriveIntentMarkers } from "#intent-markers";
19
+ import { scoreBareToponym, scoreNearMe, scoreRoutePair } from "#intent-rules";
20
+ import { createScorePOICategory, createScorePOIQuery } from "#poi";
21
+ import { scoreIntersection, scoreLandmark, scoreLocalityOnly, scorePoBox, scorePostcodeOnly, scoreStructuredAddress, scoreVague, scoreVenueLandmark, } from "#rules";
22
22
  const SCORERS = [
23
23
  { kind: "po_box", score: scorePoBox },
24
24
  { kind: "landmark", score: (i, s) => Math.max(scoreLandmark(i, s), scoreVenueLandmark(i, s)) },
@@ -1 +1 @@
1
- {"version":3,"file":"classify.js","sourceRoot":"","sources":["../classify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../lib/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC7E,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAwB,MAAM,MAAM,CAAA;AACxF,OAAO,EACN,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GAClB,MAAM,QAAQ,CAAA;AAef,MAAM,OAAO,GAA8B;IAC1C,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE;IACrC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;IAC9F,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAClD,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACnD,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACnD,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,sBAAsB,EAAE;IAC7D,2GAA2G;IAC3G,8GAA8G;IAC9G,4CAA4C;IAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACjD,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE;IAC7C,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE;IACvC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE;CACpC,CAAA;AAED;;;GAGG;AACH,SAAS,IAAI,CAAC,MAAsD;IACnE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAA;IAElD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,OAAoB,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IAExE,OAAO;QACN,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;KACtF,CAAA;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,oBAAoB,GAA2B,IAAI,GAAG,CAAY,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAA;AAElH;;;GAGG;AACH,SAAS,iBAAiB,CACzB,OAAwB,EACxB,KAA0B,EAC1B,UAA4B,EAC5B,MAAe;IAEf,MAAM,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAE/F,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,OAAO,CAAA;IAExE,MAAM,aAAa,GAAwB,mBAAmB,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;IAEpG,IAAI,CAAC,aAAa,CAAC,MAAM;QAAE,OAAO,OAAO,CAAA;IAEzC,OAAO,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,CAAA;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA0B,EAAE,KAAqB;IACjF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAC9F,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CACvB,CAAA;IAED,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAA;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CACjC,KAA0B,EAC1B,KAAqB,EACrB,OAAoB;IAEpB,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACtC,CAAC;AAcD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CACnC,OAA2B,EAAE;IAE7B,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAA;IAE3B,IAAI,CAAC,UAAU;QAAE,OAAO,YAAY,CAAA;IAEpC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAA4B,EAAE;QAC/D,MAAM,SAAS,GAAG,MAAM,EAAE,MAAM,CAAA;QAChC,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC3C,MAAM,aAAa,GAAG,mBAAmB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC9E,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAEtF,IAAI,aAAa,IAAI,CAAC,IAAI,kBAAkB,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAE9D,qGAAqG;QACrG,8GAA8G;QAC9G,2CAA2C;QAC3C,MAAM,MAAM,GAAmD;YAC9D,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;YAChD,GAAG,IAAI,CAAC,YAAY;SACpB,CAAA;QAED,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAA;QAC9D,CAAC;QAED,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAA;QACtE,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;IACrE,CAAC,CAAA;AACF,CAAC"}
package/out/index.d.ts CHANGED
@@ -12,14 +12,14 @@
12
12
  *
13
13
  * See `docs/engineering/reference/STAGES.md` § Stage 2.5 for the contract.
14
14
  */
15
- export { classifyKind, classifyKindSync, createKindClassifier } from "./classify.ts";
16
- export type { KindClassifierOpts } from "./classify.ts";
17
- export { deriveIntentMarkers } from "./intent-markers.ts";
18
- export type { IntentMarkerContext } from "./intent-markers.ts";
19
- export { nearMeSubject, scoreBareToponym, scoreNearMe, scoreRoutePair } from "./intent-rules.ts";
20
- export { matchPOICategory, matchPOISubject } from "./poi.ts";
21
- export type { POIPhraseMatch, POIPhraseLookup, POIQuerySpan, POISpatialRelation, POISubjectMatch } from "./poi.ts";
22
- export { scoreIntersection, scoreLandmark, scoreLocalityOnly, scorePoBox, scorePostcodeOnly, scoreStructuredAddress, scoreVague, scoreVenueLandmark, } from "./rules.ts";
23
- export { QueryIntentCode } from "./types.ts";
24
- export type { LocaleHint, NormalizedInputLite, QueryIntentMarker, QueryKind, QueryKindResult, QueryShapeLike, } from "./types.ts";
15
+ export { classifyKind, classifyKindSync, createKindClassifier } from "#classify";
16
+ export type { KindClassifierOpts } from "#classify";
17
+ export { deriveIntentMarkers } from "#intent-markers";
18
+ export type { IntentMarkerContext } from "#intent-markers";
19
+ export { nearMeSubject, scoreBareToponym, scoreNearMe, scoreRoutePair } from "#intent-rules";
20
+ export { matchPOICategory, matchPOISubject } from "#poi";
21
+ export type { POIPhraseMatch, POIPhraseLookup, POIQuerySpan, POISpatialRelation, POISubjectMatch } from "#poi";
22
+ export { scoreIntersection, scoreLandmark, scoreLocalityOnly, scorePoBox, scorePostcodeOnly, scoreStructuredAddress, scoreVague, scoreVenueLandmark, } from "#rules";
23
+ export { QueryIntentCode } from "#types";
24
+ export type { LocaleHint, NormalizedInputLite, QueryIntentMarker, QueryKind, QueryKindResult, QueryShapeLike, } from "#types";
25
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpF,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAChG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAElH,OAAO,EACN,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GAClB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE5C,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,cAAc,GACd,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAChF,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AAE9G,OAAO,EACN,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GAClB,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAExC,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,cAAc,GACd,MAAM,QAAQ,CAAA"}
package/out/index.js CHANGED
@@ -12,10 +12,10 @@
12
12
  *
13
13
  * See `docs/engineering/reference/STAGES.md` § Stage 2.5 for the contract.
14
14
  */
15
- export { classifyKind, classifyKindSync, createKindClassifier } from "./classify.js";
16
- export { deriveIntentMarkers } from "./intent-markers.js";
17
- export { nearMeSubject, scoreBareToponym, scoreNearMe, scoreRoutePair } from "./intent-rules.js";
18
- export { matchPOICategory, matchPOISubject } from "./poi.js";
19
- export { scoreIntersection, scoreLandmark, scoreLocalityOnly, scorePoBox, scorePostcodeOnly, scoreStructuredAddress, scoreVague, scoreVenueLandmark, } from "./rules.js";
20
- export { QueryIntentCode } from "./types.js";
15
+ export { classifyKind, classifyKindSync, createKindClassifier } from "#classify";
16
+ export { deriveIntentMarkers } from "#intent-markers";
17
+ export { nearMeSubject, scoreBareToponym, scoreNearMe, scoreRoutePair } from "#intent-rules";
18
+ export { matchPOICategory, matchPOISubject } from "#poi";
19
+ export { scoreIntersection, scoreLandmark, scoreLocalityOnly, scorePoBox, scorePostcodeOnly, scoreStructuredAddress, scoreVague, scoreVenueLandmark, } from "#rules";
20
+ export { QueryIntentCode } from "#types";
21
21
  //# sourceMappingURL=index.js.map
package/out/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAChG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG5D,OAAO,EACN,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GAClB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAEhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AAGxD,OAAO,EACN,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GAClB,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA"}
@@ -9,13 +9,13 @@
9
9
  * Three of the four intent kinds can raise their marker here, from the string alone. The fourth —
10
10
  * `bare_toponym`'s `declared_ambiguity` — cannot: its trigger is the dominance margin of the
11
11
  * RESOLVED candidate list, which does not exist yet at Stage 2.5. That one is raised by
12
- * `mailwoman/query-intent.ts` after the resolve, against the measured 0.5-log10 cut. The split is
12
+ * `mailwoman/query-intent.ts` after the resolve, against the measured 0.5-log10 threshold. The split is
13
13
  * deliberate and it is why this module never emits `declared_ambiguity`: a marker that asserted
14
14
  * ambiguity from the string alone would be declaring that every bare city name is ambiguous, which
15
15
  * is false 89.1% of the time (the measured table behind `DECISIVE_MARGIN_LOG10`).
16
16
  */
17
- import { type POIPhraseLookup } from "./poi.ts";
18
- import type { NormalizedInputLite, QueryIntentMarker, QueryKind } from "./types.ts";
17
+ import { type POIPhraseLookup } from "#poi";
18
+ import type { NormalizedInputLite, QueryIntentMarker, QueryKind } from "#types";
19
19
  /**
20
20
  * Context the marker builder needs beyond the scored kinds.
21
21
  */
@@ -1 +1 @@
1
- {"version":3,"file":"intent-markers.d.ts","sourceRoot":"","sources":["../intent-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEnF;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,mBAAmB,CAAA;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7D,GAAG,EAAE,mBAAmB,GACtB,iBAAiB,EAAE,CA8DrB"}
1
+ {"version":3,"file":"intent-markers.d.ts","sourceRoot":"","sources":["../lib/intent-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,MAAM,CAAA;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAE/E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,mBAAmB,CAAA;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7D,GAAG,EAAE,mBAAmB,GACtB,iBAAiB,EAAE,CAgErB"}
@@ -9,13 +9,13 @@
9
9
  * Three of the four intent kinds can raise their marker here, from the string alone. The fourth —
10
10
  * `bare_toponym`'s `declared_ambiguity` — cannot: its trigger is the dominance margin of the
11
11
  * RESOLVED candidate list, which does not exist yet at Stage 2.5. That one is raised by
12
- * `mailwoman/query-intent.ts` after the resolve, against the measured 0.5-log10 cut. The split is
12
+ * `mailwoman/query-intent.ts` after the resolve, against the measured 0.5-log10 threshold. The split is
13
13
  * deliberate and it is why this module never emits `declared_ambiguity`: a marker that asserted
14
14
  * ambiguity from the string alone would be declaring that every bare city name is ambiguous, which
15
15
  * is false 89.1% of the time (the measured table behind `DECISIVE_MARGIN_LOG10`).
16
16
  */
17
- import { nearMeSubject } from "./intent-rules.js";
18
- import { matchPOICategory } from "./poi.js";
17
+ import { nearMeSubject } from "#intent-rules";
18
+ import { matchPOICategory } from "#poi";
19
19
  /**
20
20
  * Build the advisories for one classified query.
21
21
  *
@@ -30,6 +30,8 @@ export function deriveIntentMarkers(kinds, ctx) {
30
30
  const fired = new Set(kinds.map((k) => k.kind));
31
31
  const markers = [];
32
32
  if (fired.has("route_pair")) {
33
+ // Whitespace-only split, not `wordsOf`: `route_pair` inputs are comma-free by construction (a comma
34
+ // disqualifies the kind), and the tokens are re-joined verbatim into the message.
33
35
  const tokens = ctx.input.normalized.trim().split(/\s+/);
34
36
  markers.push({
35
37
  kind: "route_pair",
@@ -56,9 +58,9 @@ export function deriveIntentMarkers(kinds, ctx) {
56
58
  evidence: {
57
59
  subject,
58
60
  /**
59
- * The SEAM, named but not wired (ROAD_TO_V9 §4.4 scopes v9 to classification). Photon's `/api` already accepts
60
- * `lat`/`lon` location-bias params — `photon/` is the eventual consumer of this marker, and this string is the
61
- * note that says where it plugs in.
61
+ * THE PLUG POINT, named but not wired (ROAD_TO_V9 §4.4 scopes v9 to classification). Photon's `/api` already
62
+ * accepts `lat`/`lon` location-bias params — `photon/` is the eventual consumer of this marker, and this string
63
+ * is the note that says where it plugs in.
62
64
  */
63
65
  focusParameter: "photon:lat/lon",
64
66
  },
@@ -1 +1 @@
1
- {"version":3,"file":"intent-markers.js","sourceRoot":"","sources":["../intent-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAwB,MAAM,UAAU,CAAA;AAgBjE;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAClC,KAA6D,EAC7D,GAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAY,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAwB,EAAE,CAAA;IAEvC,IAAI,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEvD,OAAO,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,eAAe;YACrB,SAAS,EAAE,iBAAiB;YAC5B,OAAO,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,2HAA2H;YACxJ,QAAQ,EAAE;gBACT,MAAM;gBACN;;;mBAGG;gBACH,eAAe,EAAE,CAAC,cAAc,EAAE,6BAA6B,CAAC;aAChE;SACD,CAAC,CAAA;IACH,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAExC,OAAO,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,IAAI,OAAO,yEAAyE;YAC7F,QAAQ,EAAE;gBACT,OAAO;gBACP;;;;mBAIG;gBACH,cAAc,EAAE,gBAAgB;aAChC;SACD,CAAC,CAAA;IACH,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;QAE3G,IAAI,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,cAAc;gBACpB,SAAS,EAAE,sBAAsB;gBACjC,OAAO,EAAE,IAAI,KAAK,CAAC,aAAa,yFAAyF;gBACzH,QAAQ,EAAE;oBACT,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvD;aACD,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"intent-markers.js","sourceRoot":"","sources":["../lib/intent-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAwB,MAAM,MAAM,CAAA;AAgB7D;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAClC,KAA6D,EAC7D,GAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAY,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAwB,EAAE,CAAA;IAEvC,IAAI,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,oGAAoG;QACpG,kFAAkF;QAClF,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEvD,OAAO,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,eAAe;YACrB,SAAS,EAAE,iBAAiB;YAC5B,OAAO,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,2HAA2H;YACxJ,QAAQ,EAAE;gBACT,MAAM;gBACN;;;mBAGG;gBACH,eAAe,EAAE,CAAC,cAAc,EAAE,6BAA6B,CAAC;aAChE;SACD,CAAC,CAAA;IACH,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAExC,OAAO,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,cAAc;YACzB,OAAO,EAAE,IAAI,OAAO,yEAAyE;YAC7F,QAAQ,EAAE;gBACT,OAAO;gBACP;;;;mBAIG;gBACH,cAAc,EAAE,gBAAgB;aAChC;SACD,CAAC,CAAA;IACH,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;QAE3G,IAAI,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,cAAc;gBACpB,SAAS,EAAE,sBAAsB;gBACjC,OAAO,EAAE,IAAI,KAAK,CAAC,aAAa,yFAAyF;gBACzH,QAAQ,EAAE;oBACT,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvD;aACD,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAA;AACf,CAAC"}
@@ -22,7 +22,7 @@
22
22
  * `near_me` DOES win its top slot (0.91), because there is no incumbent worth preserving: a query
23
23
  * ending "near me" is not a locality and answering it as one is the bug.
24
24
  */
25
- import type { NormalizedInputLite, QueryShapeLike } from "./types.ts";
25
+ import type { NormalizedInputLite, QueryShapeLike } from "#types";
26
26
  /**
27
27
  * `bare_toponym` rule: a single coherent place-name carrying no address grammar.
28
28
  *
@@ -1 +1 @@
1
- {"version":3,"file":"intent-rules.d.ts","sourceRoot":"","sources":["../intent-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAsNrE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAE1F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAgBxF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAYtF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAQhE"}
1
+ {"version":3,"file":"intent-rules.d.ts","sourceRoot":"","sources":["../lib/intent-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AA+MjE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAE1F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAgBxF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAYtF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAQhE"}
@@ -22,7 +22,7 @@
22
22
  * `near_me` DOES win its top slot (0.91), because there is no incumbent worth preserving: a query
23
23
  * ending "near me" is not a locality and answering it as one is the bug.
24
24
  */
25
- import { MAX_LOCALITY_ONLY_LENGTH, STREET_SUFFIXES } from "./rules.js";
25
+ import { isDisqualifyingStreetSuffix, MAX_LOCALITY_ONLY_LENGTH, wordsOf } from "#rules";
26
26
  /**
27
27
  * `locality_only` scores 0.85. Both refinement kinds sit under it by a whole confidence step so no float-comparison
28
28
  * accident can flip the top slot, and so the gap reads as deliberate to the next person.
@@ -173,12 +173,6 @@ const DEICTIC_LOCATOR_TAIL = /\b(?:near|close\s+to|next\s+to|around|by|closest\s
173
173
  * The adverbial half of the same class — no preposition, the deixis is baked into the word.
174
174
  */
175
175
  const DEICTIC_ADVERB_TAIL = /\b(?:nearby|near\s?by|close\s+by|around\s+here|in\s+my\s+(?:area|neighborhood|neighbourhood))\s*$/;
176
- /**
177
- * Split on whitespace + commas, the way the other rules in this package do.
178
- */
179
- function wordsOf(text) {
180
- return text.split(/[\s,]+/).filter(Boolean);
181
- }
182
176
  /**
183
177
  * True when the input carries a deictic locator tail in EITHER form.
184
178
  */
@@ -186,12 +180,12 @@ function hasDeicticTail(lowercased) {
186
180
  return DEICTIC_LOCATOR_TAIL.test(lowercased) || DEICTIC_ADVERB_TAIL.test(lowercased);
187
181
  }
188
182
  /**
189
- * The gates `bare_toponym` and `route_pair` share: no address grammar of any kind, one segment, alpha throughout.
183
+ * The conditions `bare_toponym` and `route_pair` share: no address grammar of any kind, one segment, alpha throughout.
190
184
  *
191
185
  * Returns the word list when the input clears them, `null` when it does not. Deliberately a SUPERSET of
192
- * `scoreLocalityOnly`'s gates (which admits two segments), so `bare_toponym` is a strict refinement of `locality_only`
193
- * and can never fire where `locality_only` did not — the property `intent-rules.test.ts` asserts and the reason the
194
- * ranking discipline above is enough to keep the top kind pinned.
186
+ * `scoreLocalityOnly`'s conditions (which admit two segments), so `bare_toponym` is a strict refinement of
187
+ * `locality_only` and can never fire where `locality_only` did not — the property `intent-rules.test.ts` asserts and
188
+ * the reason the ranking discipline above is enough to keep the top kind pinned.
195
189
  */
196
190
  function bareNameWords(input, shape) {
197
191
  const text = input.normalized.trim();
@@ -214,7 +208,7 @@ function bareNameWords(input, shape) {
214
208
  if (!words.length || words.length > MAX_BARE_TOPONYM_WORDS)
215
209
  return null;
216
210
  for (const word of words) {
217
- if (STREET_SUFFIXES.has(word.toLowerCase()))
211
+ if (isDisqualifyingStreetSuffix(word))
218
212
  return null;
219
213
  }
220
214
  return words;
@@ -1 +1 @@
1
- {"version":3,"file":"intent-rules.js","sourceRoot":"","sources":["../intent-rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"intent-rules.js","sourceRoot":"","sources":["../lib/intent-rules.ts"],"names":[],"mappings":"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"}
package/out/poi.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * lives in `@mailwoman/poi-taxonomy` and is wired in by `createRuntimePipeline` behind the
9
9
  * `poiQueryKind` flag (default-ON since 2026-07-20). Spec §3.1.
10
10
  */
11
- import type { NormalizedInputLite, QueryShapeLike } from "./types.ts";
11
+ import type { NormalizedInputLite, QueryShapeLike } from "#types";
12
12
  /**
13
13
  * One lexicon hit for a candidate subject phrase.
14
14
  */
@@ -32,6 +32,31 @@ export interface POIPhraseMatch {
32
32
  * Wikidata QID, when known. `kind: "brand"` only — absent when a brand resolved by name alone (no QID match).
33
33
  */
34
34
  wikidata?: string;
35
+ /**
36
+ * Whether this hit is one member of a set the caller must search TOGETHER, rather than one candidate in a preference
37
+ * list.
38
+ *
39
+ * A lookup returning several hits means two different things, and the difference decides whether narrowing to the
40
+ * first is an answer or an invented ordering. A phrase index returns the categories one typed phrase could name, the
41
+ * curated reading first (`credit union` → the `bank` rollup its synonym redirects to, then the standalone
42
+ * `credit_union` category), and the first entry IS the subject. An affordance rung returns every entity kind that
43
+ * affords ONE activity, in a stable enumeration that is not a preference, and taking the first picks a winner nobody
44
+ * authored.
45
+ *
46
+ * Set on every member of such a set. {@link matchPOISubject} then carries them all, the POI branch searches their
47
+ * union, and the candidate ordering the resolver already owns decides the answer. Absent — the committed lexicon's
48
+ * shape — keeps the first-hit reading unchanged.
49
+ */
50
+ searchAsSet?: boolean;
51
+ /**
52
+ * ISO 3166-1 alpha-2 countries the authority behind this hit scopes its claim to. Absent = the claim holds
53
+ * everywhere.
54
+ *
55
+ * A scope is a statement about ESTABLISHMENTS, so it is judged against the country of the place being searched, not
56
+ * the caller's locale: the locale is the lens the phrase is read through, and it says nothing about where the claim
57
+ * holds. `matchPOISubject` carries the value untouched; the POI intent stage binds it once the anchor has resolved.
58
+ */
59
+ countryScope?: readonly string[];
35
60
  }
36
61
  /**
37
62
  * Injected phrase→category lookup. Exact-phrase, locale-aware; returns [] on miss.
@@ -50,7 +75,19 @@ export interface POIQuerySpan {
50
75
  * Which lexicon this hit came from. Existing category lookups set `"category"` (backward-compatible default).
51
76
  */
52
77
  export interface POISubjectMatch {
78
+ /**
79
+ * The hit the subject SCORES under — its kind and its confidence. Always `matches[0]`; the two are built together in
80
+ * one place so they cannot disagree.
81
+ */
53
82
  match: POIPhraseMatch;
83
+ /**
84
+ * Every category the subject reaches, `match` first.
85
+ *
86
+ * One entry unless the lookup returned a {@link POIPhraseMatch.searchAsSet} set, in which case it holds the whole set
87
+ * and the POI branch searches their union. The order is the order the lookup returned and states no preference:
88
+ * nothing downstream may read position as rank.
89
+ */
90
+ matches: POIPhraseMatch[];
54
91
  /**
55
92
  * The matched subject text as it appeared in the query.
56
93
  */
@@ -72,6 +109,9 @@ export interface POISubjectMatch {
72
109
  * 8 tokens). Scans separator occurrences left-to-right — a lexicon phrase may itself contain a bare separator word
73
110
  * (e.g. "walk in clinic"), so the first separator isn't necessarily the right split point. Returns null when the
74
111
  * lexicon never fires — including comma-ridden full addresses whose leading segment isn't a lexicon phrase.
112
+ *
113
+ * The winning candidate's hits are carried per {@link reachedMatches}: the first hit, or the whole set when the lookup
114
+ * declared one.
75
115
  */
76
116
  export declare function matchPOISubject(text: string, locale: string | undefined, lookup: POIPhraseLookup): POISubjectMatch | null;
77
117
  /**
@@ -93,7 +133,7 @@ export declare function createScorePOIQuery(lookup: POIPhraseLookup, locale?: st
93
133
  export declare function createScorePOICategory(lookup: POIPhraseLookup, locale?: string): (input: NormalizedInputLite, shape: QueryShapeLike) => number;
94
134
  /**
95
135
  * The whole-input category hit behind a `poi_category` verdict, for the marker's evidence. `null` when the input is not
96
- * a bare category — same gates as {@link createScorePOICategory}, so the two cannot disagree.
136
+ * a bare category — same conditions as {@link createScorePOICategory}, so the two cannot disagree.
97
137
  */
98
138
  export declare function matchPOICategory(text: string, locale: string | undefined, lookup: POIPhraseLookup): POIPhraseMatch | null;
99
139
  //# sourceMappingURL=poi.d.ts.map
package/out/poi.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"poi.d.ts","sourceRoot":"","sources":["../poi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAQrE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,mBAAmB,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAA;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,aAAa,CAAC,cAAc,CAAC,CAAA;AAEhG,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAA;AAEjF,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACX;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,cAAc,CAAA;IACrB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,YAAY,CAAA;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,YAAY,CAAA;CACzB;AA2BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,eAAe,GACrB,eAAe,GAAG,IAAI,CA8DxB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,MAAM,GACb,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,KAAK,MAAM,CAiB/D;AAUD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,MAAM,GACb,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,KAAK,MAAM,CAU/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,eAAe,GACrB,cAAc,GAAG,IAAI,CAQvB"}
1
+ {"version":3,"file":"poi.d.ts","sourceRoot":"","sources":["../lib/poi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAQjE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,mBAAmB,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAA;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,aAAa,CAAC,cAAc,CAAC,CAAA;AAEhG,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAA;AAEjF,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACX;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,KAAK,EAAE,cAAc,CAAA;IACrB;;;;;;OAMG;IACH,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,YAAY,CAAA;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,YAAY,CAAA;CACzB;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,eAAe,GACrB,eAAe,GAAG,IAAI,CAoExB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,MAAM,GACb,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,KAAK,MAAM,CAiB/D;AAUD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,MAAM,GACb,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,KAAK,MAAM,CAU/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,eAAe,GACrB,cAAc,GAAG,IAAI,CAQvB"}
package/out/poi.js CHANGED
@@ -36,11 +36,25 @@ const ANCHOR_SEPARATOR = /,\s*|\s(near|in|at|around|to)\s+/gi;
36
36
  * Longest subject we accept, in tokens. Eight covers compound taxonomy phrases while bounding lexicon probes.
37
37
  */
38
38
  const MAX_SUBJECT_TOKENS = 8;
39
+ /**
40
+ * The categories one candidate subject reaches, from the hits the lookup returned for it.
41
+ *
42
+ * The whole array when the first hit declares {@link POIPhraseMatch.searchAsSet} — carried as the lookup returned it,
43
+ * never filtered, so a rung that flagged only some of its members loses nothing here and the inconsistency stays
44
+ * visible to whoever reads the set. Otherwise the first hit alone, which is the preference-list reading the committed
45
+ * phrase index has always had.
46
+ */
47
+ function reachedMatches(hits) {
48
+ return hits[0].searchAsSet ? [...hits] : [hits[0]];
49
+ }
39
50
  /**
40
51
  * Match a POI subject: the whole input, or the text before the FIRST anchor separator WHOSE PREFIX HITS THE LEXICON (≤
41
52
  * 8 tokens). Scans separator occurrences left-to-right — a lexicon phrase may itself contain a bare separator word
42
53
  * (e.g. "walk in clinic"), so the first separator isn't necessarily the right split point. Returns null when the
43
54
  * lexicon never fires — including comma-ridden full addresses whose leading segment isn't a lexicon phrase.
55
+ *
56
+ * The winning candidate's hits are carried per {@link reachedMatches}: the first hit, or the whole set when the lookup
57
+ * declared one.
44
58
  */
45
59
  export function matchPOISubject(text, locale, lookup) {
46
60
  const trimmed = text.trim();
@@ -49,8 +63,10 @@ export function matchPOISubject(text, locale, lookup) {
49
63
  return null;
50
64
  const whole = lookup(trimmed, locale);
51
65
  if (whole.length) {
66
+ const matches = reachedMatches(whole);
52
67
  return {
53
- match: whole[0],
68
+ match: matches[0],
69
+ matches,
54
70
  subject: trimmed,
55
71
  subjectSpan: { text: trimmed, start: inputStart, end: inputStart + trimmed.length },
56
72
  remainder: "",
@@ -60,7 +76,8 @@ export function matchPOISubject(text, locale, lookup) {
60
76
  if (separator.index === 0)
61
77
  continue;
62
78
  const subject = trimmed.slice(0, separator.index).trim();
63
- // Subjects only grow as the scan moves right — once over budget, later splits are too.
79
+ // Subjects only grow as the scan moves right — once over budget, later splits are too. Whitespace-only
80
+ // split, not `wordsOf`: a comma inside a subject is real content here, not a separator to erase.
64
81
  if (subject.split(/\s+/).length > MAX_SUBJECT_TOKENS)
65
82
  break;
66
83
  const hits = lookup(subject, locale);
@@ -73,8 +90,10 @@ export function matchPOISubject(text, locale, lookup) {
73
90
  const anchorOffset = trimmed.indexOf(remainder, separator.index + separator[0].length);
74
91
  const relationText = separator[1] ?? ",";
75
92
  const relationOffset = separator[1] ? separator.index + separator[0].indexOf(separator[1]) : separator.index;
93
+ const matches = reachedMatches(hits);
76
94
  return {
77
- match: hits[0],
95
+ match: matches[0],
96
+ matches,
78
97
  subject,
79
98
  subjectSpan: {
80
99
  text: subject,
@@ -147,7 +166,7 @@ export function createScorePOICategory(lookup, locale) {
147
166
  }
148
167
  /**
149
168
  * The whole-input category hit behind a `poi_category` verdict, for the marker's evidence. `null` when the input is not
150
- * a bare category — same gates as {@link createScorePOICategory}, so the two cannot disagree.
169
+ * a bare category — same conditions as {@link createScorePOICategory}, so the two cannot disagree.
151
170
  */
152
171
  export function matchPOICategory(text, locale, lookup) {
153
172
  const matched = matchPOISubject(text, locale, lookup);
package/out/poi.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"poi.js","sourceRoot":"","sources":["../poi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"poi.js","sourceRoot":"","sources":["../lib/poi.ts"],"names":[],"mappings":"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"}
package/out/rules.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * Bitter-lesson-safe: only universal structural patterns — no place-name dictionaries. ~1 small
10
10
  * regex set per new locale, not 50K dictionary entries.
11
11
  */
12
- import type { NormalizedInputLite, QueryShapeLike } from "./types.ts";
12
+ import type { NormalizedInputLite, QueryShapeLike } from "#types";
13
13
  /**
14
14
  * Longest input still plausible as a bare locality name, including a trailing region code.
15
15
  *
@@ -33,10 +33,18 @@ export declare function scoreIntersection(input: NormalizedInputLite, _shape: Qu
33
33
  */
34
34
  export declare function scoreLandmark(input: NormalizedInputLite, _shape: QueryShapeLike): number;
35
35
  /**
36
- * Street-suffix tokens that indicate an address, not a venue name. Shared with `intent-rules.ts` the intent kinds
37
- * disqualify on the same vocabulary, and a second copy would drift.
36
+ * Split on whitespace + commas and drop empty words the word grammar shared with `intent-rules.ts`. Dropping empties
37
+ * matters: a trailing comma or doubled separator otherwise yields an empty string that inflates the word count and
38
+ * falsifies every-word predicates like the proper-case check below.
38
39
  */
39
- export declare const STREET_SUFFIXES: ReadonlySet<string>;
40
+ export declare function wordsOf(text: string): string[];
41
+ /**
42
+ * True when a word is USPS street-suffix vocabulary that unambiguously signals an address — the full Pub-28 table via
43
+ * `@mailwoman/codex`, minus its curated name-prone canonicals (PARK, FIELD, HILL, LAKE, …). Those double as ordinary
44
+ * proper-name heads ("Wrigley Field", "Menlo Park"), and disqualifying on them would reject the very venue and place
45
+ * names the rules below exist to capture. Shared with `intent-rules.ts` so both rule sets read one definition.
46
+ */
47
+ export declare function isDisqualifyingStreetSuffix(word: string): boolean;
40
48
  /**
41
49
  * `landmark` rule (venue/named-place variant): short capitalized input with no street suffixes, no postcode hits, and
42
50
  * no region abbreviations. Captures "Pier 39", "Empire State Building", "Wrigley Field", "Grand Central Terminal".
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAmBrE;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAkD1C;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAQrF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAQ5F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAQxF;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAwB9C,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAkD5F;AAoBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAc3F;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAe3F;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAmBhG;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAEtF"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../lib/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAmBjE;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAkD1C;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAQrF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAQ5F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAQxF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIjE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAkD5F;AAoBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAc3F;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAe3F;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAmBhG;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAEtF"}
package/out/rules.js CHANGED
@@ -9,6 +9,7 @@
9
9
  * Bitter-lesson-safe: only universal structural patterns — no place-name dictionaries. ~1 small
10
10
  * regex set per new locale, not 50K dictionary entries.
11
11
  */
12
+ import { NAME_PRONE_US_SUFFIXES, US_STREET_SUFFIX_LOOKUP } from "@mailwoman/codex/us/street-suffix";
12
13
  /**
13
14
  * Longest input still plausible as a bare venue or landmark name. Beyond it the query is carrying an address as well,
14
15
  * and belongs to the structured-address scorer.
@@ -109,34 +110,23 @@ export function scoreLandmark(input, _shape) {
109
110
  return 0;
110
111
  }
111
112
  /**
112
- * Street-suffix tokens that indicate an address, not a venue name. Shared with `intent-rules.ts` the intent kinds
113
- * disqualify on the same vocabulary, and a second copy would drift.
113
+ * Split on whitespace + commas and drop empty words the word grammar shared with `intent-rules.ts`. Dropping empties
114
+ * matters: a trailing comma or doubled separator otherwise yields an empty string that inflates the word count and
115
+ * falsifies every-word predicates like the proper-case check below.
114
116
  */
115
- export const STREET_SUFFIXES = new Set([
116
- "st",
117
- "street",
118
- "ave",
119
- "avenue",
120
- "blvd",
121
- "boulevard",
122
- "rd",
123
- "road",
124
- "dr",
125
- "drive",
126
- "ln",
127
- "lane",
128
- "ct",
129
- "court",
130
- "pl",
131
- "place",
132
- "way",
133
- "pkwy",
134
- "parkway",
135
- "hwy",
136
- "highway",
137
- "cir",
138
- "circle",
139
- ]);
117
+ export function wordsOf(text) {
118
+ return text.split(/[\s,]+/).filter((word) => word.length > 0);
119
+ }
120
+ /**
121
+ * True when a word is USPS street-suffix vocabulary that unambiguously signals an address — the full Pub-28 table via
122
+ * `@mailwoman/codex`, minus its curated name-prone canonicals (PARK, FIELD, HILL, LAKE, …). Those double as ordinary
123
+ * proper-name heads ("Wrigley Field", "Menlo Park"), and disqualifying on them would reject the very venue and place
124
+ * names the rules below exist to capture. Shared with `intent-rules.ts` so both rule sets read one definition.
125
+ */
126
+ export function isDisqualifyingStreetSuffix(word) {
127
+ const canonical = US_STREET_SUFFIX_LOOKUP.get(word.trim().toLowerCase());
128
+ return canonical !== undefined && !NAME_PRONE_US_SUFFIXES.has(canonical);
129
+ }
140
130
  /**
141
131
  * `landmark` rule (venue/named-place variant): short capitalized input with no street suffixes, no postcode hits, and
142
132
  * no region abbreviations. Captures "Pier 39", "Empire State Building", "Wrigley Field", "Grand Central Terminal".
@@ -159,10 +149,10 @@ export function scoreVenueLandmark(input, shape) {
159
149
  const segCount = shape.segments?.length ?? 1;
160
150
  if (segCount > 2)
161
151
  return 0;
162
- // Reject if any word is a street suffix.
163
- const words = text.split(/[\s,]+/);
152
+ // Reject if any word is an unambiguous street suffix.
153
+ const words = wordsOf(text);
164
154
  for (const w of words) {
165
- if (STREET_SUFFIXES.has(w.toLowerCase()))
155
+ if (isDisqualifyingStreetSuffix(w))
166
156
  return 0;
167
157
  }
168
158
  // Reject if the first token is a pure number (house-number-leading pattern).
package/out/rules.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../lib/rules.ts"],"names":[],"mappings":"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"}
package/out/types.d.ts CHANGED
@@ -9,30 +9,8 @@
9
9
  export type { LocaleHint, QueryIntentMarker, QueryKind, QueryKindResult } from "@mailwoman/core/pipeline";
10
10
  export { QueryIntentCode } from "@mailwoman/core/pipeline";
11
11
  /**
12
- * Minimal `NormalizedInput` shape consumed by `classifyKind`. Compatible with `@mailwoman/normalize`'s output.
12
+ * The minimal input shapes consumed by `classifyKind` come from `@mailwoman/query-shape` — one declaration shared by
13
+ * every Stage-2.x consumer. `QueryShapeLike` stays this package's public name for its narrow read-only view.
13
14
  */
14
- export interface NormalizedInputLite {
15
- raw: string;
16
- normalized: string;
17
- appliedLocale?: string;
18
- }
19
- /**
20
- * Minimal `QueryShape` shape consumed by `classifyKind`. Compatible with `@mailwoman/query-shape`'s output.
21
- */
22
- export interface QueryShapeLike {
23
- knownFormats: ReadonlyArray<{
24
- format: string;
25
- span: {
26
- start: number;
27
- end: number;
28
- };
29
- confidence: number;
30
- }>;
31
- segments?: ReadonlyArray<{
32
- body: string;
33
- index: number;
34
- }>;
35
- characterClass?: string;
36
- totalLength?: number;
37
- }
15
+ export type { NormalizedInputLite, QueryShapeSegmentsView as QueryShapeLike } from "@mailwoman/query-shape";
38
16
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AACzG,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,YAAY,EAAE,aAAa,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAA;QACpC,UAAU,EAAE,MAAM,CAAA;KAClB,CAAC,CAAA;IACF,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACzD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AACzG,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D;;;GAGG;AACH,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAA"}
package/out/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mailwoman/kind-classifier",
3
- "version": "9.2.0",
3
+ "version": "9.3.0",
4
4
  "description": "Stage 2.5 of the runtime pipeline — categorize inputs by query shape (postcode_only / locality_only / structured_address / intersection / po_box / landmark / vague). Rule-based for v1.",
5
5
  "license": "AGPL-3.0-only OR LicenseRef-Commercial",
6
6
  "repository": {
@@ -24,30 +24,44 @@
24
24
  "!test/**"
25
25
  ],
26
26
  "type": "module",
27
+ "sideEffects": false,
28
+ "imports": {
29
+ "#*": {
30
+ "types": "./out/*.d.ts",
31
+ "node": "./out/*.js",
32
+ "default": "./out/*.js"
33
+ }
34
+ },
27
35
  "exports": {
28
36
  "./package.json": "./package.json",
29
37
  ".": {
30
38
  "types": "./out/index.d.ts",
39
+ "node": "./out/index.js",
31
40
  "default": "./out/index.js"
32
41
  },
33
42
  "./classify": {
34
43
  "types": "./out/classify.d.ts",
44
+ "node": "./out/classify.js",
35
45
  "default": "./out/classify.js"
36
46
  },
37
47
  "./types": {
38
48
  "types": "./out/types.d.ts",
49
+ "node": "./out/types.js",
39
50
  "default": "./out/types.js"
40
51
  },
41
52
  "./intent-rules": {
42
53
  "types": "./out/intent-rules.d.ts",
54
+ "node": "./out/intent-rules.js",
43
55
  "default": "./out/intent-rules.js"
44
56
  },
45
57
  "./rules": {
46
58
  "types": "./out/rules.d.ts",
59
+ "node": "./out/rules.js",
47
60
  "default": "./out/rules.js"
48
61
  },
49
62
  "./poi": {
50
63
  "types": "./out/poi.d.ts",
64
+ "node": "./out/poi.js",
51
65
  "default": "./out/poi.js"
52
66
  }
53
67
  },
@@ -57,34 +71,46 @@
57
71
  "./package.json": "./package.json",
58
72
  ".": {
59
73
  "types": "./out/index.d.ts",
74
+ "node": "./out/index.js",
60
75
  "default": "./out/index.js"
61
76
  },
62
77
  "./classify": {
63
78
  "types": "./out/classify.d.ts",
79
+ "node": "./out/classify.js",
64
80
  "default": "./out/classify.js"
65
81
  },
66
82
  "./types": {
67
83
  "types": "./out/types.d.ts",
84
+ "node": "./out/types.js",
68
85
  "default": "./out/types.js"
69
86
  },
70
87
  "./intent-rules": {
71
88
  "types": "./out/intent-rules.d.ts",
89
+ "node": "./out/intent-rules.js",
72
90
  "default": "./out/intent-rules.js"
73
91
  },
74
92
  "./rules": {
75
93
  "types": "./out/rules.d.ts",
94
+ "node": "./out/rules.js",
76
95
  "default": "./out/rules.js"
77
96
  },
78
97
  "./poi": {
79
98
  "types": "./out/poi.d.ts",
99
+ "node": "./out/poi.js",
80
100
  "default": "./out/poi.js"
81
101
  }
102
+ },
103
+ "imports": {
104
+ "#*": {
105
+ "types": "./out/*.d.ts",
106
+ "node": "./out/*.js",
107
+ "default": "./out/*.js"
108
+ }
82
109
  }
83
110
  },
84
111
  "dependencies": {
85
- "@mailwoman/core": "9.2.0"
86
- },
87
- "devDependencies": {
88
- "@mailwoman/query-shape": "9.2.0"
112
+ "@mailwoman/codex": "9.3.0",
113
+ "@mailwoman/core": "9.3.0",
114
+ "@mailwoman/query-shape": "9.3.0"
89
115
  }
90
116
  }
package/types.ts DELETED
@@ -1,34 +0,0 @@
1
- /**
2
- * @copyright Sister Software
3
- * @license AGPL-3.0
4
- * @author Teffen Ellis, et al.
5
- */
6
-
7
- /**
8
- * Re-exports of the canonical types from `@mailwoman/core/pipeline`.
9
- */
10
- export type { LocaleHint, QueryIntentMarker, QueryKind, QueryKindResult } from "@mailwoman/core/pipeline"
11
- export { QueryIntentCode } from "@mailwoman/core/pipeline"
12
-
13
- /**
14
- * Minimal `NormalizedInput` shape consumed by `classifyKind`. Compatible with `@mailwoman/normalize`'s output.
15
- */
16
- export interface NormalizedInputLite {
17
- raw: string
18
- normalized: string
19
- appliedLocale?: string
20
- }
21
-
22
- /**
23
- * Minimal `QueryShape` shape consumed by `classifyKind`. Compatible with `@mailwoman/query-shape`'s output.
24
- */
25
- export interface QueryShapeLike {
26
- knownFormats: ReadonlyArray<{
27
- format: string
28
- span: { start: number; end: number }
29
- confidence: number
30
- }>
31
- segments?: ReadonlyArray<{ body: string; index: number }>
32
- characterClass?: string
33
- totalLength?: number
34
- }