Skip to content
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
6aee36c
docs(21): context for New Brunswick Government Open Data
mariomeyer Jul 27, 2026
e2d4dd9
docs(21): research New Brunswick Government Open Data
mariomeyer Jul 30, 2026
ddefa28
docs(21): add validation strategy
mariomeyer Jul 30, 2026
71d8459
docs(21): plan New Brunswick phase — 7 plans, 6 waves, 22 tools
mariomeyer Jul 30, 2026
5c62b79
docs(21): create phase plan
mariomeyer Jul 30, 2026
95fd2ba
feat(21-01): tracer — nb_get_crown_land end-to-end through GeoNB ArcG…
mariomeyer Jul 30, 2026
a206b9d
test(21-01): add failing tests for GeoNB ArcGIS Server directory enum…
mariomeyer Jul 30, 2026
978aae1
feat(21-01): extend shared/arcgis_hub.py with bare ArcGIS Server dire…
mariomeyer Jul 30, 2026
52ce8b0
docs(21-01): live-verify all 11 curated GeoNB layer ids in 21-SPIKE.md
mariomeyer Jul 30, 2026
625f128
feat(21-01): expand new_brunswick scaffold to full contract surface
mariomeyer Jul 30, 2026
d6de3de
docs(21-01): add plan 01 summary
mariomeyer Jul 30, 2026
25c3ab9
docs(21-01): append self-check results to plan 01 summary
mariomeyer Jul 30, 2026
a7db209
docs(21-01): complete New Brunswick wave 0 scaffold plan
mariomeyer Jul 30, 2026
7da90e2
feat(21-02): implement federal CKAN discovery client functions (Task 1)
mariomeyer Jul 30, 2026
ee218b5
feat(21-02): add five nb_ federal CKAN discovery tools (Task 2)
mariomeyer Jul 30, 2026
d14de80
feat(21-02): add gnb.socrata.com discovery surface (Task 3, checkpoin…
mariomeyer Jul 30, 2026
2af864d
docs(21-02): complete federal CKAN discovery plan
mariomeyer Jul 30, 2026
9baae12
feat(21-03): add 6 bilingual nb_ prompts — 3 guided workflows + 3 qui…
mariomeyer Jul 30, 2026
3b70258
feat(21-03): add 7 zero-parameter nb_ resources — GeoNB catalogue, st…
mariomeyer Jul 30, 2026
def7e19
docs(21-03): complete New Brunswick prompts and resources plan
mariomeyer Jul 30, 2026
5c7e718
feat(21-04): GeoNB discovery trio — stands in for the 401-ing Hub Sea…
mariomeyer Jul 30, 2026
fa8ad43
feat(21-04): flood — hazard index and historical flood limits
mariomeyer Jul 30, 2026
9adaaf8
feat(21-04): water — wetlands (filter-required) and contaminated sites
mariomeyer Jul 30, 2026
5ddd3ea
docs(21-04): complete GeoNB discovery + flood/water plan
mariomeyer Jul 30, 2026
910727b
feat(21-05): parcels and civic addresses — NB's geocoding pair, both …
mariomeyer Jul 30, 2026
a3a5bc8
docs(21-05): complete parcels and civic addresses plan
mariomeyer Jul 30, 2026
29de32e
feat(21-06): health facilities and public schools — layer-dispatch tools
mariomeyer Jul 30, 2026
dbd3b23
feat(21-06): NB 511 — three key-gated transport tools + manifest inte…
mariomeyer Jul 30, 2026
2c28893
docs(21-06): complete health/education/transport plan
mariomeyer Jul 30, 2026
79729f1
test(21-07): live MCP-layer integration coverage for all 22 New Bruns…
mariomeyer Jul 30, 2026
bf2b9d5
docs(21-07): sync catalogue and correct New Brunswick documentation
mariomeyer Jul 30, 2026
898a68e
docs(21-07): register NB-01..NB-25 requirements and resolve COVERAGE.…
mariomeyer Jul 30, 2026
2e475fd
docs(21-07): complete New Brunswick integration coverage and docs syn…
mariomeyer Jul 30, 2026
72e5c97
docs(21): add code review report
mariomeyer Jul 30, 2026
84192e3
fix(21): CR-01 close FILTER_REQUIRED guard bypass (whitespace + LIKE …
mariomeyer Jul 30, 2026
791f30b
fix(21): WR-01 parenthesize fq conjunction so NB org scope can't be e…
mariomeyer Jul 30, 2026
f9626dd
fix(21): WR-02 echo clamped limit/offset actually sent upstream, not …
mariomeyer Jul 30, 2026
2ff6931
fix(21): WR-03 reject non-positive limit in nb_query_dataset before a…
mariomeyer Jul 30, 2026
a32b398
fix(21): WR-04 strengthen nb_ tool-name guard beyond bare startswith …
mariomeyer Jul 30, 2026
734f54b
fix(21): IN-01 import schemas.py into client.py, matching sibling-mod…
mariomeyer Jul 30, 2026
ba73712
docs(21): add code review fix report
mariomeyer Jul 30, 2026
a5bb452
docs(phase-21): complete phase execution
mariomeyer Jul 30, 2026
60b4113
docs(phase-21): resolve stale STATE.md checkpoint and focus entries
mariomeyer Jul 30, 2026
5f52caa
docs(phase-21): evolve PROJECT.md after phase completion
mariomeyer Jul 30, 2026
5ffea24
docs(phase-21): add security threat verification
mariomeyer Jul 30, 2026
264449c
fix(21): F1 reject delimiter-breaking extra_fq in NB CKAN discovery
mariomeyer Jul 31, 2026
3ecf46f
fix(21): F2 clamp limit to [1, MAX_RECORDS] centrally in _geonb_query
mariomeyer Jul 31, 2026
193c091
fix(21): F3 reject non-positive limit in NB gnb.socrata.com queries
mariomeyer Jul 31, 2026
6e81ebe
fix(21): F4 include Latitude/Longitude in nb_get_contaminated_sites
mariomeyer Jul 31, 2026
4964e77
fix(21): F5 include LATITUDE/LONGITUDE/COUNTY/PID in nb_get_civic_add…
mariomeyer Jul 31, 2026
5edda91
test(21): assert live field presence for F4/F5 out_fields widenings
mariomeyer Jul 31, 2026
499a76c
fix(21): treat whitespace-only extra_fq as absent, not a malformed Lu…
mariomeyer Jul 31, 2026
5660496
docs(21): reopen and re-close T-21-03/T-21-04 after Codex review of P…
mariomeyer Jul 31, 2026
b5120aa
fix(21): G1 scope package_show to the NB organization
mariomeyer Jul 31, 2026
820855a
fix(21): G2 cap fetch_query_dataset limit at MAX_RECORDS
mariomeyer Jul 31, 2026
af307ec
fix(21): G3 update stale MODULE_DESCRIPTION for four upstream surfaces
mariomeyer Jul 31, 2026
9c24fae
fix(21): G4 correct nb_flood_risk_assessment's unexecutable workflow
mariomeyer Jul 31, 2026
90434c1
docs(21): add round-2 code review fix report
mariomeyer Jul 31, 2026
533c69f
fix(21): make nb_crown_land_report's county argument executable
mariomeyer Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .planning/PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,16 @@ The shared datastore is a new architectural concept for mcp-canada. It adds a `d
| "Inspired by" attribution | Credit Aryan Jhaveri without implying fork/derivation | — Pending |
| Try to fix SSL (not disable) | Security-first; fall back to scoped disable if needed | — Pending |

## Current State

Phase 21 complete (2026-07-30) — `new_brunswick` module shipped, the 8th province in the
provincial rollout: 22 tools, 6 prompts, 7 resources. Repo-wide totals now 295 tools across
21 modules.

> **Doc drift note:** this file is scoped to the v1.1 StatCan + Datastore milestone. The
> provincial rollout (Phases 11–23) is tracked only in ROADMAP.md and is not represented in the
> Requirements lists above, and the StatCan/datastore items still listed under **Active** were
> delivered in Phases 7–10. Reconciling both is out of scope for Phase 21 and needs its own pass.

---
*Last updated: 2026-04-07 after initialization*
*Last updated: 2026-07-30 after Phase 21 (New Brunswick) completion*
67 changes: 66 additions & 1 deletion .planning/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,45 @@ Primary portal is **data.novascotia.ca** — a **Socrata** (Tyler Technologies)
- [x] **NS-17**: Agent can get Nova Scotia chronic disease prevalence dispatched by disease: Literal["ami","diabetes","copd","hypertension","asthma"] (`24qf-ntke`, `cumi-sw99`, `ua9e-4pss`, `sztc-sewr`, `2bih-5dgk`) with year, zone (normalized from health_zone/zone), sex, agegroup, population, crude_prevalence_rate; invalid disease returns INVALID_INPUT
- [x] **NS-18**: All Nova Scotia tools follow mcp-canada conventions (standalone @tool, make_response/make_error envelope, Use-for + Keywords single-line docstrings, ns_ prefix), are discoverable via discover_tools, and 6 prompts + 7 resources are auto-discovered by FileSystemProvider

### New Brunswick Government Open Data

Backfilled 2026-07-30 alongside Phase 21's own closing plan (21-07) — the phase entered
planning with `Requirements: TBD` and these IDs were registered here immediately after
planning closed, matching the Alberta/Manitoba/Saskatchewan/Nova Scotia precedent. Three
discovery surfaces: **federal CKAN** (`open.canada.ca`, filtered server-side to
`organization:nb`, non-overridable — T-21-04), **GeoNB** (`geonb.snb.ca`, bare ArcGIS Server —
no Hub Search API in front, HTTP 401 on the Hub), and **`gnb.socrata.com`** (NB's real
provincial Socrata portal, 312 datasets, keyless — the 21-01 Task 2 blocking-checkpoint
decision, option-a, which overturned 21-CONTEXT.md's "NB has no provincial catalogue"
premise). Transport (511) is key-gated behind `NEW_BRUNSWICK_511_KEY`, mirroring the Manitoba
`Five11NotConfigured` pattern. Module prefix `nb_`.

- [x] **NB-01**: Agent can search New Brunswick's federal-CKAN catalogue (open.canada.ca, 221 datasets) by keyword, server-side scoped to `organization:nb` and never caller-overridable (T-21-04)
- [x] **NB-02**: Agent can get full metadata for a single New Brunswick federal-CKAN dataset by id, with bilingual title/notes resolution correct for both a genuinely-bilingual record and NB's separately-published FR/EN duplicate-record pairs (D-12)
- [x] **NB-03**: Agent can pull rows out of a New Brunswick federal-CKAN resource (CSV/XLSX/XLS/JSON/GEOJSON auto-routed through `fetch_and_parse`); an unparseable format (NB has 25 ZIP and 25 FGDB resources) returns a metadata-only success naming the download url, never an error
- [x] **NB-04**: Agent can list New Brunswick's publishing organization and sections on the federal-CKAN catalogue
- [x] **NB-05**: Agent can list New Brunswick's dataset subject, topic and format facets on the federal-CKAN catalogue (NB packages carry an empty CKAN `groups` array, so facets stand in)
- [x] **NB-06**: Two additive bare-ArcGIS-Server enumeration functions (`list_arcgis_server_services`, `get_arcgis_server_layers`) added to the shared `shared/arcgis_hub.py` client, pinned by outgoing-param contract tests — reusable by any future province with a bare ArcGIS Server portal and no Hub Search API in front
- [x] **NB-07**: Agent can list GeoNB's ~62 ArcGIS Server map services via a live REST-directory walk, standing in for the Hub Search API that returns HTTP 401 — 5 basemap tile services and the retired `GeoNB_DNR_WildlifeRefuges` placeholder hidden by default, each carrying an `exclusion_reason` when included
- [x] **NB-08**: Agent can get the real layer ids, live record counts and field names of a single GeoNB service before querying it — GeoNB layer ids are non-guessable and do not always start at 0 (Crown Land's real layer id is 3, not 0)
- [x] **NB-09**: Agent can query any GeoNB layer by service name and layer id — the long-tail escape hatch that keeps every un-curated GeoNB service reachable, including the equivalents of mineral occurrences (NB-15) and provincial parks (NB-16)
- [x] **NB-10**: Agent can get New Brunswick flood hazard index polygons (`GeoNB_ENV_FloodHazardIndex`, layer 0) filterable by source map sheet
- [x] **NB-11**: Agent can get New Brunswick's recorded historical flood limits (`GeoNB_ENV_Historical_Floods`), dispatched by event — 2008/2018 share the main layer (0), 1973 resolves to its own dedicated layer (8)
- [x] **NB-12**: Agent can get New Brunswick wetland polygons (`GeoNB_ENV_Wetlands`, layer 2) filtered by class or status; an unfiltered call is rejected with `INVALID_INPUT` before any network request (the layer holds 163,206 rows — T-21-03)
- [x] **NB-13**: Agent can get New Brunswick contaminated site points (`GeoNB_ELG_Contaminated_Sites`, layer 0) with both `Status_E` and `Status_F` (bilingual status text) always returned regardless of which field the filter matched
- [x] **NB-14**: Agent can get New Brunswick Crown Land parcels (`GeoNB_DNR_Crown_Land`, layer 3, never layer 0) — the phase tracer, proving the bare-ArcGIS-Server pattern end to end before any other tool was written
- [x] **NB-15**: Mineral occurrences (`GeoNB_DNR_MineralOccurrences`, layer 0) are reachable via `nb_query_geonb_layer` — superseded by NB-09; the 21-01 Task 2 checkpoint (option-a) dropped the standalone `nb_get_mineral_occurrences` tool to hold the 22-tool budget after adding the two `gnb.socrata.com` tools
- [x] **NB-16**: Provincial parks (`GeoNB_DNR_ProvincialParks`, layer 0) are reachable via `nb_query_geonb_layer` — superseded by NB-09, the same checkpoint tradeoff as NB-15
- [x] **NB-17**: Agent can resolve a New Brunswick property by PID or list parcels by county through `nb_get_parcels`, over the province's 604,520-parcel cadastre; an unfiltered call is rejected with `INVALID_INPUT` before any network request (T-21-03)
- [x] **NB-18**: Agent can resolve a civic address by community, street or civic number through `nb_get_civic_addresses`, over 373,172 address points with the street-type field in both official languages (`ST_TYPE_E`/`ST_TYPE_F`); an unfiltered call is rejected with `INVALID_INPUT` before any network request (T-21-03)
- [x] **NB-19**: Agent can find New Brunswick hospitals, after-hours clinics, adult residential centres, nursing homes and pharmacies through one `nb_get_health_facilities` call dispatched by `facility_type` across 6 separate GeoNB layers, each with its own live-verified name field
- [x] **NB-20**: Agent can find New Brunswick public schools in the anglophone or francophone sector through `nb_get_public_schools`, dispatched by `sector`, filterable by district (live-verified `ASD-*`/`DSF-*` short codes)
- [x] **NB-21**: Agent can get current New Brunswick road events (closures, construction, incidents) from NB 511; returns a bilingual `NOT_CONFIGURED` envelope — never a raised exception — when `NEW_BRUNSWICK_511_KEY` is absent (D-10)
- [x] **NB-22**: Agent can get current New Brunswick winter road conditions from NB 511; same `NOT_CONFIGURED` behaviour when the key is absent
- [x] **NB-23**: Agent can get New Brunswick traffic camera locations from NB 511; same `NOT_CONFIGURED` behaviour when the key is absent — none of the three 511 tools ever echoes the key's value into a response (T-21-02)
- [x] **NB-24**: All New Brunswick tools follow mcp-canada conventions (standalone @tool, make_response/make_error envelope, Use-for + Keywords single-line docstrings, `nb_` prefix, bilingual `lang` argument), are discoverable via discover_tools, 6 prompts + 7 resources are auto-discovered by FileSystemProvider, the generated catalogue and README stay in sync, and coverage holds at or above 95%
- [x] **NB-25**: `gnb.socrata.com` (312 New Brunswick datasets, keyless) is documented as a live provincial Socrata portal in the module's own portal guide, in CLAUDE.md, and in COVERAGE.md — the 21-01 Task 2 blocking-checkpoint decision (option-a: two new `nb_` discovery tools reusing `shared/socrata.py` verbatim) and its consequences for the curated tool manifest (NB-15/NB-16 dropped to the long tail) are recorded

## v2 Requirements

### Extended Datastore
Expand Down Expand Up @@ -576,11 +615,37 @@ Primary portal is **data.novascotia.ca** — a **Socrata** (Tyler Technologies)
| NS-16 | Phase 20 | Complete |
| NS-17 | Phase 20 | Complete |
| NS-18 | Phase 20 | Complete |
| NB-01 | Phase 21 | Complete |
| NB-02 | Phase 21 | Complete |
| NB-03 | Phase 21 | Complete |
| NB-04 | Phase 21 | Complete |
| NB-05 | Phase 21 | Complete |
| NB-06 | Phase 21 | Complete |
| NB-07 | Phase 21 | Complete |
| NB-08 | Phase 21 | Complete |
| NB-09 | Phase 21 | Complete |
| NB-10 | Phase 21 | Complete |
| NB-11 | Phase 21 | Complete |
| NB-12 | Phase 21 | Complete |
| NB-13 | Phase 21 | Complete |
| NB-14 | Phase 21 | Complete |
| NB-15 | Phase 21 | Complete (superseded by NB-09 — reachable via nb_query_geonb_layer) |
| NB-16 | Phase 21 | Complete (superseded by NB-09 — reachable via nb_query_geonb_layer) |
| NB-17 | Phase 21 | Complete |
| NB-18 | Phase 21 | Complete |
| NB-19 | Phase 21 | Complete |
| NB-20 | Phase 21 | Complete |
| NB-21 | Phase 21 | Complete |
| NB-22 | Phase 21 | Complete |
| NB-23 | Phase 21 | Complete |
| NB-24 | Phase 21 | Complete |
| NB-25 | Phase 21 | Complete |

**Coverage:**
- v1 requirements: 73 total (added 27 Alberta requirements in Phase 17)
- Mapped to phases: 73
- Unmapped: 0
- New Brunswick requirements: 25 total (Phase 21)
- York Region requirements: 14 total (Phase 14)
- IRCC requirements: 9 total (Phase 11)
- Ontario requirements: 8 total (Phase 12)
Expand All @@ -593,4 +658,4 @@ Primary portal is **data.novascotia.ca** — a **Socrata** (Tyler Technologies)

---
*Requirements defined: 2026-04-07*
*Last updated: 2026-06-15 after Phase 20 planning (added NS-01…NS-18)*
*Last updated: 2026-07-30 after Phase 21 close (added NB-01…NB-25)*
31 changes: 27 additions & 4 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,37 @@ Plans:

### Phase 21: New Brunswick Government Open Data

**Goal:** [To be planned]
**Requirements**: TBD
**Goal:** Ship a `new_brunswick` module exposing NB provincial data as MCP tools — the 8th province in the rollout. 22 tools: 5 federal-CKAN discovery tools (`organization:nb`, 221 datasets — NB has no provincial CKAN), 2 `gnb.socrata.com` discovery tools (NB's provincial Socrata portal, 312 datasets, keyless — added by the 21-01 checkpoint, which live-disproved CONTEXT.md's "no provincial catalogue" claim), 3 GeoNB ArcGIS **Server** discovery tools (the ArcGIS Hub 401s, so the REST directory is enumerated instead), 9 curated geospatial tools across flood/water, Crown land/forestry, parcels/civic address and health/education, and 3 key-gated 511 transport stubs. `nb_get_provincial_parks` and `nb_get_mineral_occurrences` were traded to the long tail to hold the 22-tool budget; both stay reachable via `nb_query_geonb_layer`. Follows the 7-file module pattern; adds two additive bare-ArcGIS-Server enumerator functions to `shared/arcgis_hub.py`.
**Requirements**: NB-01..NB-25, ERR-01..ERR-07
**Depends on:** Phase 20
**Plans:** 0 plans
**Plans:** 7/7 plans complete

Plans:

- [ ] TBD (run /gsd:plan-phase 21 to break down)
**Wave 0** *(tracer + blocking `checkpoint:decision` — must resolve before the tool manifest is locked)*

- [x] 21-01-PLAN.md — Crown Land tracer end-to-end, gnb.socrata.com discovery-surface checkpoint, `shared/arcgis_hub.py` enumerator + live layer-id spike, full module scaffold

**Wave 1** *(blocked on Wave 0 completion; 21-02 and 21-03 run in parallel — disjoint files)*

- [x] 21-02-PLAN.md — Federal CKAN discovery: 5 tools, bilingual `title_translated`/`notes_translated` resolution, outgoing-param contract test
- [x] 21-03-PLAN.md — 6 prompts + 7 zero-parameter resources (GeoNB catalogue, counties, health/school dispatch, portal guide, query guide, report template)

**Wave 2** *(blocked on Wave 1 completion)*

- [x] 21-04-PLAN.md — GeoNB discovery (3 tools) + flood & water curated (flood hazard, historical floods, wetlands with pre-network guard, contaminated sites)

**Wave 3** *(blocked on Wave 2 completion)*

- [x] 21-05-PLAN.md — Crown land/forestry completion (minerals, parks) + parcels & civic addresses, both guarded over 604K/373K layers

**Wave 4** *(blocked on Wave 3 completion)*

- [x] 21-06-PLAN.md — Health facilities & public schools layer-dispatch tools + 3 NB 511 `NOT_CONFIGURED` transport stubs

**Wave 5** *(blocked on Wave 4 completion)*

- [x] 21-07-PLAN.md — Live MCP-layer integration coverage for all 22 tools, catalogue/README/CLAUDE.md sync, NB-01..NB-25 backfill, COVERAGE.md finalization

### Phase 22: Newfoundland and Labrador Government Open Data

Expand Down
Loading
Loading