Skip to content

CivicRecords AI v1.2.0

Choose a tag to compare

@github-actions github-actions released this 23 Apr 21:36
· 139 commits to master since this release

CivicRecords AI v1.2.0

Released 2026-04-23. Tagged at commit cc06abc. CI green on all three required jobs (Frontend, Backend, T2C bootstrap-failure smoke) on the release-prep chain 0b404c4673e140cc06abc. 617 backend pytest + 36 frontend vitest all passing.

About this release

CivicRecords AI is an open-source, locally-hosted AI system for municipal open-records request processing. Every deployment is a sovereign instance owned by the city — no cloud, no telemetry, no outbound data transfer.

Windows installer is UNSIGNED by design. On first run, Windows SmartScreen will show "Windows protected your PC — Unknown publisher." To proceed: click More infoRun anyway, then confirm UAC. See installer/windows/README.md for the full walkthrough.

Headline: ENG-001 CLOSED

Both halves of the connector-credentials exposure gap are now shut:

  • T2B runtime (earlier sprint) — connection_config redacted from GET /datasources/ via DataSourceRead; admin-only DataSourceAdminRead on write endpoints.
  • Tier 6 at-rest (this release)data_sources.connection_config JSONB is now stored as a versioned Fernet envelope ({"v":1,"ct":"<fernet-token>"}, AES-128-CBC + HMAC-SHA256) via a transparent SQLAlchemy EncryptedJSONB TypeDecorator. pg_dump output, restored backups, and DB-superuser sessions see ciphertext only. Runtime callers still see a plain dict — zero API / admin-UI surface change.

Operator breaking change: ENCRYPTION_KEY env var is now required at startup. The installer auto-generates a Fernet key on fresh installs and prints a loud "BACK IT UP SEPARATELY FROM YOUR DATABASE" banner. Existing deployments need:

ENCRYPTION_KEY=$(python -c 'import base64,os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())')
echo "ENCRYPTION_KEY=$ENCRYPTION_KEY" >> .env

Then back the key up. Losing it means losing decryption access to every connector's credentials. Key rotation is not supported in v1.2.0 and is tracked as a future slice; the "v":1 envelope tag leaves the door open.

Tier 5 — complete

Five slices shipped 2026-04-22 → 2026-04-23 and tagged in this release:

  • T5A — Onboarding persistence. The single-phase adaptive interview now actually persists each answer onto the CityProfile singleton (creating the row on the first answer), normalizes yes/no for has_dedicated_it, and transitions onboarding_status (not_startedin_progresscomplete). Skip advances the walk truthfully. Migration 018_city_profile_state_nullable.py.
  • T5B — First-boot baseline seeding. app/main.lifespan auto-seeds 175 state-scoped exemption rules across 51 jurisdictions, 5 compliance templates, and 12 notification templates. Idempotent via skip-if-exists — admin customizations survive re-seed. Every run emits created / skipped counts.
  • T5C — 4-model Gemma 4 installer picker. gemma4:e4b default. Fake tags (gemma4:12b, gemma4:27b) purged repo-wide. gemma4:26b / gemma4:31b selectable with explicit "requires stronger hardware" acknowledgment against the locked 32 GB target profile.
  • T5D — Install-time portal switch. New PORTAL_MODE env var (private default, public opt-in). Private mode keeps the deployment staff-only — login screen is the only externally reachable page. Public mode exposes exactly three surfaces: public landing page, resident-registration path, and authenticated records-request submission form for UserRole.PUBLIC. Anonymous submission, published-records search, resident dashboard, and track-my-request remain out of scope. Also fixes a pre-existing bug where UserCreate silently forced self-registrants to UserRole.STAFF.
  • T5E — Windows unsigned double-click installer. Real .exe built with Inno Setup 6.x via choco install innosetup -y + installer/windows/build-installer.sh on windows-latest. Start-vs-Install shortcut flow split (Start CivicRecords AI = daily docker compose up -d; Install or Repair CivicRecords AI = full bootstrap + picker + model pull). Tag-derived version sourcing — no hardcoded drift.

Also in v1.2.0 (pre-release unreleased work folded in)

  • April 14 accessibility Sessions A/B/B.1/B.2/C — global :focus-visible fallback + Geist Variable font, ring-[3px] focus on Button/Input/SelectTrigger, data-table keyboard row activation, 15 SelectTrigger aria-labels, LoadingRegion with role="status", CardTitle as prop, 7 <h2> in RequestDetail, dialog focus trap verified.
  • April 19–21 security remediation T2A–T3D — CI ratchet (GitHub Actions, collected-vs-passed cross-check, bootstrap-failure smoke test); 24 dept-scoped handlers enforce require_department_scope; 404/403 info-leak unified; Pattern D list fail-open closed; review_fee_waiver gap fixed; T2B connection_config redaction (runtime half of ENG-001); T2C FIRST_ADMIN_PASSWORD startup validator + SSRF host validator; T3A admin-create path fix; T3D OpenAPI typegen + stale-check gate.
  • April 21–22 T4A/B/C — responsive AppShell with mobile drawer; Dashboard/Settings service-health truth fix; Add-Source wizard accessibility + validation; Button forwardRef migration; UX-001 radiogroup keyboard handler; QA-001 Settings-page hallucinated-rows removal.

Release-pipeline corrections during the cut

Two release-path corrections landed on top of the initial chore(release): cut v1.2.0 commit. Both are build-pipeline only — zero product behaviour change, no T5E scope reopen:

  • 673e140 — unbreak build-installer.sh on windows-latest. Git Bash / MSYS2 was splitting /DMyAppVersion=… into two args before handing off to ISCC; fix pre-converts the .iss path with cygpath -w and sets MSYS_NO_PATHCONV=1 MSYS2_ARG_CONV_EXCL='*' for the single ISCC invocation.
  • cc06abc — unbreak artifact handoff between the build job and the create-release job. actions/upload-artifact@v7 preserves the build/ prefix relative to GITHUB_WORKSPACE, so the upload step was globbing the wrong directory; fix locates via find and emits an actionable error if nothing matches.

Downloads

  • Windows (double-click installer): CivicRecordsAI-1.2.0-Setup.exe — attached below, with matching .sha256. Verify on the operator machine with Get-FileHash .\CivicRecordsAI-1.2.0-Setup.exe -Algorithm SHA256 and compare against the checksum file.
  • Linux / macOS (guided script): clone the repo at v1.2.0 and run ./install.sh. Prerequisites and step-by-step walkthrough: README.md and USER-MANUAL.md. Cross-platform native installer parity is explicit follow-on, not shipped here.

Docs

Not shipped (explicit scope discipline)

  • No key rotation / MultiFernet / KMS / HSM / Vault integration. One key per deployment for v1.2.0.
  • No signed Windows installer. Unsigned by design per the Scott-locked T5E signing posture α.
  • No native macOS / Linux installer.
  • No public portal expansion beyond T5D's three minimal surfaces (landing + resident-registration + authenticated submission).
  • No anonymous walk-up submission.