Skip to content

Commit 3521196

Browse files
committed
docs(20.2): record live validation and close the state item
317 live integration tests pass against HEAD in 2m30s. CI matrix extended to Python 3.14 and green. Closes the malformed-JSON open item, noting the sweep found the problem wider than the original note assumed (108 uncovered tools, not 7 mislabelling modules) and that Codex surfaced two further defects in the fix itself.
1 parent 9e2c843 commit 3521196

2 files changed

Lines changed: 30 additions & 11 deletions

File tree

.planning/STATE.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
gsd_state_version: 1.0
33
milestone: v1.1
44
milestone_name: Statistics Canada + Datastore
5-
current_phase: 20
6-
current_phase_name: Finish integration de-masking and fix the failures it exposed
5+
current_phase: "20.2"
6+
current_phase_name: Normalize tool error handling and guard malformed upstream JSON
77
status: awaiting_merge
8-
stopped_at: "Phase 20.1 complete; PR #2 open with all four CI gates green"
9-
last_updated: "2026-07-26T02:32:53.467Z"
10-
last_activity: 2026-07-25
11-
last_activity_desc: Phase 20.1 executed end to end
8+
stopped_at: "Phase 20.2 complete; PR #3 green on 3.12/3.13/3.14, Codex findings addressed"
9+
last_updated: "2026-07-26T04:00:00.000Z"
10+
last_activity: 2026-07-26
11+
last_activity_desc: Phase 20.2 executed and verified; 317 live tests green
1212
progress:
1313
total_phases: 36
1414
completed_phases: 16
@@ -28,10 +28,12 @@ See: .planning/PROJECT.md (updated 2026-04-07)
2828

2929
## Current Position
3030

31-
Phase: 20.1 of 36 — COMPLETE and MERGED to main (PR #2, merge commit 98dee90)
32-
Plan: 6 of 6 complete
33-
Status: next is Phase 20.2 (run /gsd-plan-phase 20.2)
34-
Last activity: 2026-07-26 — Phase 20.1 merged; all four CI gates green
31+
Phase: 20.2 of 36 — COMPLETE, awaiting merge (PR #3)
32+
Plan: 1 of 1 complete
33+
Status: PR #3 green on Python 3.12/3.13/3.14; both Codex findings fixed; next is Phase 21
34+
Last activity: 2026-07-26 — Phase 20.2 executed and verified; 317 live tests green
35+
36+
Phase 20.1 is COMPLETE and MERGED to main (PR #2, merge commit 98dee90).
3537

3638
Progress: [████░░░░░░] 44%
3739

@@ -94,7 +96,7 @@ Open defect (found 2026-07-26, deferred to its own phase):
9496
behind an env-var key like Manitoba 511. Alberta AHS, parks, forest-area and
9597
Saskatchewan/Manitoba Hub services were probed at the same time and are healthy.
9698

97-
- **Malformed-JSON masking is broader than the spot Codex flagged.****now Phase 20.2.**
99+
- ~~**Malformed-JSON masking is broader than the spot Codex flagged.**~~**CLOSED by Phase 20.2** (PR #3). The sweep found the problem was wider than this note assumed: 108 of 271 tools had no catch-all at all, not just 7 modules with a mislabelling `ValueError` arm. Codex then found two further defects in the fix itself — `upstream_guard` was never a true catch-all (a `KeyError` still escaped), and `pydantic.ValidationError` also subclasses `ValueError`, so upstream schema drift was blamed on the caller. Both fixed. Original note kept below for the record:
98100
`upstream_guard` is fixed, which covers drug_database and nutrient_file (they use
99101
their own clients). But `shared/http.py:api_get` returns `response.json()` with no
100102
decode guard, and ~40 `except ValueError -> INVALID_INPUT` arms across statcan,

.planning/phases/20.2-normalize-tool-error-handling-and-guard-malformed-upstream-j/20.2-VERIFICATION.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ failure — never as caller error, never as an escaped exception.
3131
| 9 | `upstream_guard` really is a catch-all | ✓ VERIFIED | `test_upstream_guard_really_is_a_catch_all` raises a custom exception type through it |
3232
| 10 | Upstream schema drift is not caller error | ✓ VERIFIED | `test_pydantic_validation_error_is_upstream_not_caller_error` |
3333
| 11 | Coverage stays above the 95% gate | ✓ VERIFIED | 97.09% |
34+
| 12 | Guards behave against real APIs | ✓ VERIFIED | 317 live integration tests passed in 2m30s against HEAD |
35+
| 13 | Supported Python versions actually tested | ✓ VERIFIED | CI matrix now 3.12 / 3.13 / 3.14, all green |
3436

3537
## Requirements Coverage
3638

@@ -86,6 +88,21 @@ Both were verified against the runtime before acting (`pydantic.ValidationError.
8688
and the guard's actual `except` list), and both fixes were confirmed non-vacuous
8789
by reverting `envelope.py` — all 6 new tests fail without it.
8890

91+
## Live validation
92+
93+
`uv run pytest tests/integration/ -m integration -k "not drug and not nutrient"`
94+
against HEAD: **317 passed, 23 deselected, 2m30s.** Zero failures, so decorating
95+
108 tools changed no live behaviour on the success path while closing the leak
96+
on the failure path.
97+
98+
Drug/nutrient were excluded because the Phase 20.1 caveat still applies (Health
99+
Canada rate-limits them under full-suite load; they pass in isolation). Their 16
100+
tools were already guarded before this phase, so they are not what 20.2 changed.
101+
102+
Note on Python versions: every local check in this phase ran on **3.14.4**, while
103+
CI proved only 3.12 and 3.13 despite `requires-python = ">=3.12"`. 3.14 was added
104+
to the matrix and passes; the stale classifiers were corrected at the same time.
105+
89106
## Known limitation
90107

91108
`upstream_guard` reads `lang` from `kwargs`, so a tool invoked with `lang`

0 commit comments

Comments
 (0)