Skip to content

Schema layer, CONTRIBUTING, error-report pipeline, disclaimer, CI, and re-checked city research - #12

Open
inkxel wants to merge 3 commits into
masterfrom
claude/project-status-next-steps-wu340s
Open

Schema layer, CONTRIBUTING, error-report pipeline, disclaimer, CI, and re-checked city research#12
inkxel wants to merge 3 commits into
masterfrom
claude/project-status-next-steps-wu340s

Conversation

@inkxel

@inkxel inkxel commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

Works through essentially all of SPEC.md's open "Next steps" in two batches.

Design layer (new schema/):

  • common-schema.md — normalized per-feature shape: two required timestamps (data_as_of vs source.last_synced, which diverge exactly when it matters — e.g. LA's frozen 2015 permit data), untyped geometry, a six-state per-category status enum (built/in_progress/gap/not_applicable/unconfirmed/paused), and jurisdiction-wide default rules (the Walnut, CA unsigned-rule case) as a schema-level concept.
  • coverage-registry.md — the new data/coverage_registry.json shape (per-category status + population), replacing the old flat shape that couldn't represent a confirmed gap distinctly from "not built yet."
  • error-report-pipeline.md — the anti-spam design for the GitHub-issue-based report flow: no backend, no anonymous auto-post; a real GitHub account to submit through is the moderation step.

Implementation:

  • Migrated data/coverage_registry.json and all three LA adapter scripts to the new schema.
  • app.jsisCovered() for the new registry shape; a shared confidenceBadge() across all three category panels (previously permits-only); reportIssueUrl()/reportLink() wiring a "Report a problem" link into every panel; a first-run disclaimer modal (localStorage-gated) alongside the persistent footer.
  • .github/ISSUE_TEMPLATE/data-issue.yml + unsigned-rule.yml for the two report types.
  • CONTRIBUTING.md — dashboard-tracing method, the schema, a worked LA-adapter example, how to register a jurisdiction.
  • scripts/validate_schema.py — enforces the common schema and registry schema against real files, not just documents them.
  • .github/workflows/lint.yml — runs the validator, Python/YAML/JS syntax checks on every PR.
  • .github/workflows/label-data-issues.yml — auto-applies city:*/category:* labels on new reports by parsing the issue-form body.

Research:

  • ParkUsher investigated directly (closed, thin, paywalled meters — doesn't change Seattle/SF prioritization).
  • Chicago's meters gap re-checked (held up; a shaky private-API fallback surfaced) and Seattle's sweeping gap re-checked (overturned — real data on a second ArcGIS portal, with a source-confirmed voluntary-enforcement caveat) via the dashboard-tracing method.
  • San Diego added as a researched adapter candidate (~4th on the ranked list).
  • Municipal-code hosting checked for LA/NYC/Chicago/Seattle/DC.
  • SPEC.md's coverage table, ranked candidate list, and Next Steps checklist updated throughout.

Known limitation

This session's sandbox blocks direct HTTPS to arcgis.com, data.seattle.gov, data.sandiego.gov, data.cityofchicago.org, and even unpkg.com at the network-policy level (re-confirmed directly, not assumed). That leaves three things genuinely still blocked, flagged explicitly in SPEC.md rather than glossed over:

  • A second real adapter (LA is still the only jurisdiction with actual code in scripts/) — writing one against guessed column names without being able to confirm them wasn't worth the risk of shipping something that looks done but silently isn't.
  • Live-verifying the Seattle/San Diego dashboard traces (currently corroborated by search, not by query).
  • The Walnut, CA jurisdiction-wide-rule entry — needs a real Census place_id, and fabricating one would plant wrong data in the one file this project treats as hand-maintained ground truth.

Test plan

  • python3 -m py_compile scripts/*.py
  • node --check app.js
  • python3 scripts/validate_schema.py all (registry + any adapter output present)
  • YAML validity on all issue templates and workflows
  • Disclaimer modal + localStorage gating verified end-to-end via Playwright against synthetic fixtures (real map/data rendering blocked by the sandbox's CDN restriction, noted above)
  • confidenceBadge() date-threshold logic and reportIssueUrl() query-param construction verified in isolation
  • Issue-form field-extraction and slugify logic in label-data-issues.yml verified against realistic form bodies
  • Live GitHub Action behavior (label creation/application) — untestable outside a real repo context; review before merge

🤖 Generated with Claude Code

https://claude.ai/code/session_01YbWncp7hgMyXKDvX4oUcBM


Generated by Claude Code

claude and others added 3 commits July 12, 2026 16:55
…ror-report pipeline, disclaimer, and re-checked city research

Design layer (schema/):
- common-schema.md: normalized per-feature shape, two required timestamps
  (data_as_of vs source.last_synced), untyped geometry, six-state per-category
  status enum, and jurisdiction-wide default rules (the Walnut, CA case) as a
  schema-level concept distinct from block/zone data.
- coverage-registry.md: the new data/coverage_registry.json shape (per-category
  status + population), replacing the old flat status+array shape that couldn't
  represent a confirmed gap distinctly from "not built yet."
- error-report-pipeline.md: the anti-spam design for GitHub-issue-based reports
  -- no backend, no anonymous auto-post, a real GitHub account to submit
  through IS the moderation step.

Implementation:
- Migrated data/coverage_registry.json and the three LA adapter scripts to the
  new schema (data_as_of set explicitly, not just source.last_synced).
- app.js: isCovered() helper for the new per-category registry shape; shared
  confidenceBadge() across all three category panels (previously permits-only);
  reportIssueUrl()/reportLink() wiring a "Report a problem" link into every
  panel; first-run disclaimer modal (localStorage-gated) alongside the
  persistent footer strip.
- .github/ISSUE_TEMPLATE/data-issue.yml + unsigned-rule.yml for the two report
  types the pipeline needs.
- CONTRIBUTING.md: dashboard-tracing method, the common schema, the worked LA
  adapter example, and how to register a jurisdiction.

Research:
- Investigated ParkUsher directly (not open source, no API, meters paywalled,
  uneven coverage) -- doesn't change Seattle/SF prioritization.
- Re-checked Chicago's meters gap (held up, with a real-but-unverified private
  fallback surfaced) and Seattle's sweeping gap (overturned -- real data on a
  second ArcGIS portal, with a source-confirmed voluntary-enforcement caveat)
  via the dashboard-tracing method.
- Added San Diego as a researched adapter candidate.
- Checked municipal-code hosting for LA/NYC/Chicago/Seattle/DC.
- Updated SPEC.md's coverage table, ranked candidate list, and Next Steps
  checklist throughout to reflect all of the above.

Known limitation: this session's network policy blocked direct HTTPS to
arcgis.com/data.seattle.gov/data.sandiego.gov, so the Seattle and San Diego
dashboard-traces are corroborated by search, not confirmed by live query --
flagged explicitly in both the affected research files and SPEC.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YbWncp7hgMyXKDvX4oUcBM
Two of the five open items from the last round were achievable without
network access; the other three (a second real adapter, live-verifying
Seattle/San Diego, and the Walnut jurisdiction-rule entry) are re-confirmed
still blocked on the same restrictive sandbox network policy -- checked
directly again rather than assumed.

- scripts/validate_schema.py: checks adapter GeoJSON output against
  schema/common-schema.md's required fields, and coverage_registry.json
  against schema/coverage-registry.md's status enum. Turns the schema docs
  into something enforced, not just documented.
- .github/workflows/lint.yml: runs the validator (registry mode), Python
  syntax, YAML validity, and app.js syntax on every PR.
- .github/workflows/label-data-issues.yml: parses new data-issue/unsigned-rule
  reports for their Jurisdiction/Category fields and applies city:*/category:*
  labels automatically, closing the manual-triage step
  schema/error-report-pipeline.md flagged as a future improvement.
- CONTRIBUTING.md: documents the validator as a pre-PR step and the new CI.
- SPEC.md: updated Next Steps to reflect what closed vs. what's still
  genuinely blocked, with the network check re-run and cited directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YbWncp7hgMyXKDvX4oUcBM
Picked up PR #12 locally per its own handoff instructions: all four
scripts/fetch_*.py adapters run clean from a local environment (LA +
Census TIGERweb both reachable), and scripts/validate_schema.py confirms
the real parking-data adapters + coverage registry validate against the
common schema with zero violations.

One new finding: validate_schema.py's `all` mode also checks
data/national-places.geojson against the common schema, which is scoped
to parking-rule categories only (sweeping/meters/permits/crime) per its
own spec -- the boundary layer isn't one of those. Cosmetic (~59K
false-positive violations in `all` only), not a data problem, not fixed
yet.

Chicago adapter is next but not started this round.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants