diff --git a/CHANGELOG.md b/CHANGELOG.md
index a720571..6fe1d26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [0.2.2] - 2026-05-23
+
+- Narrow truth-repair release. No functional upgrade.
+- Exists solely to supersede the false v1.0.0 release from 2026-05-21 in
+ GitHub's Latest impression.
+- CivicCore pin unchanged.
+
## [0.2.0] - 2026-05-10
- Demoted the false v1.0.0 release label after the external CivicSuite audit found this module is a recovery/foundation module, not a canonical spec-complete v1 product.
diff --git a/README.md b/README.md
index 603e77a..fe5d3f6 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
CivicZone is CivicSuite's parcel-aware zoning and land-use Q&A module.
-Current state: **v0.2.1 corrective demotion state - scaffold with partial persistence/workflow plumbing; no real AI layer, full frontend, real municipal data/search, or public-use gate. The previous v1.0.0 release was published in error and is superseded by this honest sub-1.0.0 label.**. This repo contains a FastAPI service, health/root endpoints, documentation gates, canonical zoning schema models, Alembic migrations, deterministic parcel/zone lookup, cited use-rule lookup, cited dimensional-rule prechecks, resident Q&A with refusal and escalation rules, optional database-backed parcel/rule, resident-question ledger, and staff-workflow records through `CIVICZONE_PARCEL_RULE_DB_URL`, staff-only precedent protection, a browser-usable resident UI at `/civiczone`, a staff workflow shell at `/civiczone/staff`, adversarial local integration mocks, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment. See [docs/release-recovery-status.md](docs/release-recovery-status.md) for historical recovery context and current release evidence.
+Current state: **v0.2.2 corrective demotion state - scaffold with partial persistence/workflow plumbing; no real AI layer, full frontend, real municipal data/search, or public-use gate. This narrow truth-repair release is no functional upgrade; it exists solely to supersede the false v1.0.0 release from 2026-05-21 in GitHub's Latest impression. The CivicCore pin is unchanged.**. This repo contains a FastAPI service, health/root endpoints, documentation gates, canonical zoning schema models, Alembic migrations, deterministic parcel/zone lookup, cited use-rule lookup, cited dimensional-rule prechecks, resident Q&A with refusal and escalation rules, optional database-backed parcel/rule, resident-question ledger, and staff-workflow records through `CIVICZONE_PARCEL_RULE_DB_URL`, staff-only precedent protection, a browser-usable resident UI at `/civiczone`, a staff workflow shell at `/civiczone/staff`, adversarial local integration mocks, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment. See [docs/release-recovery-status.md](docs/release-recovery-status.md) for historical recovery context and current release evidence.
## Product Boundaries
diff --git a/README.txt b/README.txt
index 7fc89e2..1d0bb26 100644
--- a/README.txt
+++ b/README.txt
@@ -3,7 +3,7 @@ CivicZone
CivicZone is CivicSuite's parcel-aware zoning and land-use Q&A module.
-Current state: CivicZone v0.2.1 corrective demotion state. This repo contains a FastAPI service, health/root endpoints, documentation gates, canonical zoning schema models, Alembic migrations, deterministic parcel/zone lookup, cited use-rule lookup, cited dimensional-rule prechecks, resident Q&A with refusal and escalation rules, optional database-backed parcel/rule, resident-question ledger, and staff-workflow records through CIVICZONE_PARCEL_RULE_DB_URL, staff-only precedent protection, a browser-usable resident UI at /civiczone, a staff workflow shell at /civiczone/staff, adversarial local integration mocks, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment. See docs/release-recovery-status.md for historical recovery context and current release evidence.
+Current state: CivicZone v0.2.2 corrective demotion state. This narrow truth-repair release is no functional upgrade; it exists solely to supersede the false v1.0.0 release from 2026-05-21 in GitHub's Latest impression, with the CivicCore pin unchanged. This repo contains a FastAPI service, health/root endpoints, documentation gates, canonical zoning schema models, Alembic migrations, deterministic parcel/zone lookup, cited use-rule lookup, cited dimensional-rule prechecks, resident Q&A with refusal and escalation rules, optional database-backed parcel/rule, resident-question ledger, and staff-workflow records through CIVICZONE_PARCEL_RULE_DB_URL, staff-only precedent protection, a browser-usable resident UI at /civiczone, a staff workflow shell at /civiczone/staff, adversarial local integration mocks, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment. See docs/release-recovery-status.md for historical recovery context and current release evidence.
Product boundaries:
diff --git a/SECURITY.md b/SECURITY.md
index eebefeb..0e6f93e 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,5 +1,5 @@
# Security
-CivicZone Current version: 0.2.1. The previous v1.0.0 release was published in error and does not prove public-use readiness. Deploy it only for local scaffold evaluation behind the city's trusted access layer, set `CIVICZONE_STAFF_TRUSTED_PROXY_CIDRS` for the reverse proxy allowed to inject staff headers, review local parcel/rule data with planning staff, and route official zoning determinations to municipal staff.
+CivicZone Current version: 0.2.2. This is a narrow truth-repair release with no functional upgrade. The previous v1.0.0 release was published in error and does not prove public-use readiness. Deploy it only for local scaffold evaluation behind the city's trusted access layer, set `CIVICZONE_STAFF_TRUSTED_PROXY_CIDRS` for the reverse proxy allowed to inject staff headers, review local parcel/rule data with planning staff, and route official zoning determinations to municipal staff.
Report suspected vulnerabilities privately to the project maintainer. Do not open public issues containing exploit details, secrets, or sensitive municipal data.
diff --git a/USER-MANUAL.md b/USER-MANUAL.md
index da12529..bf34b01 100644
--- a/USER-MANUAL.md
+++ b/USER-MANUAL.md
@@ -4,7 +4,7 @@
CivicZone answers routine parcel-aware zoning questions with citations. It is not a zoning determination tool, not legal advice, and not a replacement for planner review.
-Current state: CivicZone v0.2.1 corrective demotion state. The package, health endpoints, canonical zoning schema, Alembic migrations, parcel/zone lookup API, use and dimensional rule APIs, optional database-backed parcel/rule lookup records, resident question ledger records, staff workflow records, citation-grounded resident Q&A, staff-only precedent protection, local adversarial integration mocks, a browser-usable resident UI at `/civiczone`, a staff workflow shell at `/civiczone/staff`, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment exist. CivicZone does not call live external systems by default, does not provide legal advice, and does not make official zoning determinations. See `docs/release-recovery-status.md` for historical recovery context and current release evidence.
+Current state: CivicZone v0.2.2 corrective demotion state. This narrow truth-repair release is no functional upgrade; it exists solely to supersede the false v1.0.0 release from 2026-05-21 in GitHub's Latest impression, with the CivicCore pin unchanged. The package, health endpoints, canonical zoning schema, Alembic migrations, parcel/zone lookup API, use and dimensional rule APIs, optional database-backed parcel/rule lookup records, resident question ledger records, staff workflow records, citation-grounded resident Q&A, staff-only precedent protection, local adversarial integration mocks, a browser-usable resident UI at `/civiczone`, a staff workflow shell at `/civiczone/staff`, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment exist. CivicZone does not call live external systems by default, does not provide legal advice, and does not make official zoning determinations. See `docs/release-recovery-status.md` for historical recovery context and current release evidence.
The resident UI shows a pre-filled parcel lookup for `123 Main St`, zone context, use and dimensional-rule cards, citation-grounded Q&A, visible loading/success/empty/error/partial state guidance, and planner-escalation guidance. It is informational only: it is not legal advice, not a zoning determination, and not a replacement for municipal planning staff.
@@ -55,7 +55,7 @@ bash scripts/verify-release.sh
flowchart LR
Resident["Resident or planner"] --> CivicZone["CivicZone"]
CivicZone --> CivicCore["CivicCore v1.1.0"]
-CivicZone --> CivicCode["CivicCode v1.0.0+"]
+CivicZone --> CivicCode["CivicCode released context"]
CivicZone --> LocalMocks["Adversarial local integration mocks"]
CivicZone -. configured .-> GIS["Local GIS / assessor datasets"]
```
diff --git a/USER-MANUAL.txt b/USER-MANUAL.txt
index 261bd5d..0d7e66e 100644
--- a/USER-MANUAL.txt
+++ b/USER-MANUAL.txt
@@ -4,7 +4,7 @@
CivicZone answers routine parcel-aware zoning questions with citations. It is not a zoning determination tool, not legal advice, and not a replacement for planner review.
-Current state: CivicZone v0.2.1 corrective demotion state. The package, health endpoints, canonical zoning schema, Alembic migrations, parcel/zone lookup API, use and dimensional rule APIs, optional database-backed parcel/rule lookup records, resident question ledger records, staff workflow records, citation-grounded resident Q&A, staff-only precedent protection, local adversarial integration mocks, a browser-usable resident UI at /civiczone, a staff workflow shell at /civiczone/staff, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment exist. CivicZone does not call live external systems by default, does not provide legal advice, and does not make official zoning determinations. See docs/release-recovery-status.md for historical recovery context and current release evidence.
+Current state: CivicZone v0.2.2 corrective demotion state. This narrow truth-repair release is no functional upgrade; it exists solely to supersede the false v1.0.0 release from 2026-05-21 in GitHub's Latest impression, with the CivicCore pin unchanged. The package, health endpoints, canonical zoning schema, Alembic migrations, parcel/zone lookup API, use and dimensional rule APIs, optional database-backed parcel/rule lookup records, resident question ledger records, staff workflow records, citation-grounded resident Q&A, staff-only precedent protection, local adversarial integration mocks, a browser-usable resident UI at /civiczone, a staff workflow shell at /civiczone/staff, trusted-proxy staff access validation, and CivicCore v1.1.0 release-wheel dependency alignment exist. CivicZone does not call live external systems by default, does not provide legal advice, and does not make official zoning determinations. See docs/release-recovery-status.md for historical recovery context and current release evidence.
The resident UI shows a pre-filled parcel lookup for `123 Main St`, zone context, use and dimensional-rule cards, citation-grounded Q&A, visible loading/success/empty/error/partial state guidance, and planner-escalation guidance. It is informational only: it is not legal advice, not a zoning determination, and not a replacement for municipal planning staff.
@@ -55,7 +55,7 @@ bash scripts/verify-release.sh
flowchart LR
Resident["Resident or planner"] --> CivicZone["CivicZone"]
CivicZone --> CivicCore["CivicCore v1.1.0"]
-CivicZone --> CivicCode["CivicCode v1.0.0+"]
+CivicZone --> CivicCode["CivicCode released context"]
CivicZone --> LocalMocks["Adversarial local integration mocks"]
CivicZone -. configured .-> GIS["Local GIS / assessor datasets"]
```
diff --git a/civiczone/__init__.py b/civiczone/__init__.py
index 48fa1e9..a00a780 100644
--- a/civiczone/__init__.py
+++ b/civiczone/__init__.py
@@ -1,3 +1,3 @@
"""CivicZone package."""
-__version__ = "0.2.1"
+__version__ = "0.2.2"
diff --git a/civiczone/main.py b/civiczone/main.py
index 99da827..5770887 100644
--- a/civiczone/main.py
+++ b/civiczone/main.py
@@ -73,7 +73,7 @@ def root() -> dict[str, str]:
"version": __version__,
"status": "v1 parcel-aware zoning Q&A runtime",
"message": (
- "CivicZone v0.2.1 provides deterministic parcel lookup, cited use-rule lookup, cited dimensional prechecks, "
+ "CivicZone v0.2.2 provides deterministic parcel lookup, cited use-rule lookup, cited dimensional prechecks, "
"resident zoning Q&A with refusal and escalation rules, staff workflow APIs, optional database-backed parcel/rule and question-ledger records, "
"canonical zoning schema migrations, adversarial local integration mocks, an accessible resident UI, and a staff workflow UI shell. "
"It does not make zoning determinations, give legal advice, replace planner review, or call live external systems by default."
diff --git a/civiczone/public_ui.py b/civiczone/public_ui.py
index 696d166..e85a8d7 100644
--- a/civiczone/public_ui.py
+++ b/civiczone/public_ui.py
@@ -208,7 +208,7 @@ def render_public_lookup_page() -> str:
CivicZone resident lookup
Parcel zoning context, cited use rules, dimensional standards, and escalation paths for residents. CivicZone provides information only; planning staff make official determinations.
- v0.2.1 corrective demotion state
+ v0.2.2 corrective demotion state
diff --git a/docs/index.html b/docs/index.html
index 7810f95..4393fda 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -23,9 +23,9 @@
Zoning answers with citations, not guesses.
CivicZone is the parcel-aware zoning and land-use module for CivicSuite. It helps residents and planners find routine zoning information while escalating actual determinations to staff.
- v0.2.1 corrective demotion state
+ v0.2.2 corrective demotion state
Current State
-
CivicZone v0.2.1 includes the FastAPI service, root endpoint, health endpoint, documentation gates, canonical zoning schema, Alembic migrations, parcel/zone lookup API, use and dimensional rule APIs, optional database-backed parcel/rule lookup records, resident question ledger, staff workflow records via CIVICZONE_PARCEL_RULE_DB_URL, citation-grounded resident Q&A, staff-only precedent protection, local adversarial integration mocks, browser-usable resident UI, staff workflow shell, trusted-proxy staff access validation, and CivicCore v1.1.0 dependency alignment. CivicZone does not make official zoning determinations, provide legal advice, or call live external vendor systems by default.
+
CivicZone v0.2.2 is a narrow truth-repair release with no functional upgrade. It exists solely to supersede the false v1.0.0 release from 2026-05-21 in GitHub's Latest impression; the CivicCore pin is unchanged. CivicZone includes the FastAPI service, root endpoint, health endpoint, documentation gates, canonical zoning schema, Alembic migrations, parcel/zone lookup API, use and dimensional rule APIs, optional database-backed parcel/rule lookup records, resident question ledger, staff workflow records via CIVICZONE_PARCEL_RULE_DB_URL, citation-grounded resident Q&A, staff-only precedent protection, local adversarial integration mocks, browser-usable resident UI, staff workflow shell, trusted-proxy staff access validation, and CivicCore v1.1.0 dependency alignment. CivicZone does not make official zoning determinations, provide legal advice, or call live external vendor systems by default.
diff --git a/pyproject.toml b/pyproject.toml
index a9cdc6a..4f6ed4c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "civiczone"
-version = "0.2.1"
+version = "0.2.2"
description = "CivicZone runtime foundation for parcel-aware zoning and land-use Q&A."
readme = "README.md"
requires-python = ">=3.11"
diff --git a/scripts/verify-release.sh b/scripts/verify-release.sh
index c6c9c52..cc37d92 100755
--- a/scripts/verify-release.sh
+++ b/scripts/verify-release.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
-VERSION="0.2.1"
+VERSION="0.2.2"
find_python() {
local candidates=()
@@ -40,7 +40,7 @@ ${PYTHON_BIN} - <<'PY'
from pathlib import Path
import tomllib
-version = "0.2.1"
+version = "0.2.2"
root = Path(".")
pyproject = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
assert pyproject["project"]["version"] == version, pyproject["project"]["version"]
@@ -56,7 +56,7 @@ for path in [
"SECURITY.md",
]:
text = (root / path).read_text(encoding="utf-8")
- assert "0.2.1" in text, f"missing release version in {path}"
+ assert "0.2.2" in text, f"missing release version in {path}"
assert "0.1.0.dev0" not in text, f"stale dev version in {path}"
print("PASS: version surfaces synchronized")
PY
@@ -81,8 +81,8 @@ from pathlib import Path
import hashlib
dist = Path("dist")
-wheel = dist / "civiczone-0.2.1-py3-none-any.whl"
-sdist = dist / "civiczone-0.2.1.tar.gz"
+wheel = dist / "civiczone-0.2.2-py3-none-any.whl"
+sdist = dist / "civiczone-0.2.2.tar.gz"
assert wheel.exists(), f"missing {wheel}"
assert sdist.exists(), f"missing {sdist}"
lines = []
diff --git a/tests/test_milestone_7_public_ui_accessibility.py b/tests/test_milestone_7_public_ui_accessibility.py
index 723fb44..ffd2f45 100644
--- a/tests/test_milestone_7_public_ui_accessibility.py
+++ b/tests/test_milestone_7_public_ui_accessibility.py
@@ -17,7 +17,7 @@ def test_public_ui_route_returns_accessible_html() -> None:
assert 'Skip to main content' in text
assert '' in text
assert "aria-live=\"polite\"" in text
- assert "v0.2.1 corrective demotion state" in text
+ assert "v0.2.2 corrective demotion state" in text
assert '' in text
diff --git a/tests/test_runtime_foundation.py b/tests/test_runtime_foundation.py
index 577b2e9..5185851 100644
--- a/tests/test_runtime_foundation.py
+++ b/tests/test_runtime_foundation.py
@@ -12,7 +12,7 @@
def test_package_version_is_100() -> None:
- assert civiczone.__version__ == "0.2.1"
+ assert civiczone.__version__ == "0.2.2"
def test_pyproject_uses_published_civiccore_release_wheel() -> None:
@@ -33,7 +33,7 @@ def test_root_endpoint_states_runtime_boundary() -> None:
payload = response.json()
assert payload["name"] == "CivicZone"
- assert payload["version"] == "0.2.1"
+ assert payload["version"] == "0.2.2"
assert payload["status"] == "v1 parcel-aware zoning Q&A runtime"
assert "optional database-backed parcel/rule" in payload["message"]
assert "staff workflow APIs" in payload["message"]
@@ -49,7 +49,7 @@ def test_health_endpoint_reports_versions() -> None:
assert payload["status"] == "ok"
assert payload["service"] == "civiczone"
- assert payload["version"] == "0.2.1"
+ assert payload["version"] == "0.2.2"
assert payload["civiccore_version"] == "1.1.0"
@@ -82,5 +82,5 @@ def test_current_docs_mark_v1_label_as_recovered_without_product_release_overcla
for path, text in docs.items():
lowered = text.lower()
- assert "0.2.1" in lowered, path
+ assert "0.2.2" in lowered, path
assert "provisional" not in lowered, path